mirror of
https://github.com/gogs/gogs.git
synced 2026-02-01 12:09:26 +01:00
Migrate issue_label.go and comment.go from XORM to GORM
Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
This commit is contained in:
@@ -7,11 +7,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/unknwon/com"
|
||||
log "unknwon.dev/clog/v2"
|
||||
"xorm.io/xorm"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
"github.com/unknwon/com"
|
||||
"gorm.io/gorm"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/errutil"
|
||||
"gogs.io/gogs/internal/markup"
|
||||
@@ -50,47 +49,50 @@ type Comment struct {
|
||||
ID int64
|
||||
Type CommentType
|
||||
PosterID int64
|
||||
Poster *User `xorm:"-" json:"-" gorm:"-"`
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
Issue *Issue `xorm:"-" json:"-" gorm:"-"`
|
||||
Poster *User `gorm:"-" json:"-"`
|
||||
IssueID int64 `gorm:"index"`
|
||||
Issue *Issue `gorm:"-" json:"-"`
|
||||
CommitID int64
|
||||
Line int64
|
||||
Content string `xorm:"TEXT"`
|
||||
RenderedContent string `xorm:"-" json:"-" gorm:"-"`
|
||||
Content string `gorm:"type:text"`
|
||||
RenderedContent string `gorm:"-" json:"-"`
|
||||
|
||||
Created time.Time `xorm:"-" json:"-" gorm:"-"`
|
||||
Created time.Time `gorm:"-" json:"-"`
|
||||
CreatedUnix int64
|
||||
Updated time.Time `xorm:"-" json:"-" gorm:"-"`
|
||||
Updated time.Time `gorm:"-" json:"-"`
|
||||
UpdatedUnix int64
|
||||
|
||||
// Reference issue in commit message
|
||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
||||
CommitSHA string `gorm:"type:varchar(40)"`
|
||||
|
||||
Attachments []*Attachment `xorm:"-" json:"-" gorm:"-"`
|
||||
Attachments []*Attachment `gorm:"-" json:"-"`
|
||||
|
||||
// For view issue page.
|
||||
ShowTag CommentTag `xorm:"-" json:"-" gorm:"-"`
|
||||
ShowTag CommentTag `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
func (c *Comment) BeforeInsert() {
|
||||
c.CreatedUnix = time.Now().Unix()
|
||||
c.UpdatedUnix = c.CreatedUnix
|
||||
}
|
||||
|
||||
func (c *Comment) BeforeUpdate() {
|
||||
c.UpdatedUnix = time.Now().Unix()
|
||||
}
|
||||
|
||||
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
|
||||
switch colName {
|
||||
case "created_unix":
|
||||
c.Created = time.Unix(c.CreatedUnix, 0).Local()
|
||||
case "updated_unix":
|
||||
c.Updated = time.Unix(c.UpdatedUnix, 0).Local()
|
||||
func (c *Comment) BeforeCreate(tx *gorm.DB) error {
|
||||
if c.CreatedUnix == 0 {
|
||||
c.CreatedUnix = tx.NowFunc().Unix()
|
||||
}
|
||||
if c.UpdatedUnix == 0 {
|
||||
c.UpdatedUnix = c.CreatedUnix
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Comment) loadAttributes(e Engine) (err error) {
|
||||
func (c *Comment) BeforeUpdate(tx *gorm.DB) error {
|
||||
c.UpdatedUnix = tx.NowFunc().Unix()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Comment) AfterFind(tx *gorm.DB) error {
|
||||
c.Created = time.Unix(c.CreatedUnix, 0).Local()
|
||||
c.Updated = time.Unix(c.UpdatedUnix, 0).Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Comment) loadAttributes(tx *gorm.DB) (err error) {
|
||||
if c.Poster == nil {
|
||||
c.Poster, err = Handle.Users().GetByID(context.TODO(), c.PosterID)
|
||||
if err != nil {
|
||||
@@ -104,12 +106,12 @@ func (c *Comment) loadAttributes(e Engine) (err error) {
|
||||
}
|
||||
|
||||
if c.Issue == nil {
|
||||
c.Issue, err = getRawIssueByID(e, c.IssueID)
|
||||
c.Issue, err = getRawIssueByID(tx, c.IssueID)
|
||||
if err != nil {
|
||||
return errors.Newf("getIssueByID [%d]: %v", c.IssueID, err)
|
||||
}
|
||||
if c.Issue.Repo == nil {
|
||||
c.Issue.Repo, err = getRepositoryByID(e, c.Issue.RepoID)
|
||||
c.Issue.Repo, err = getRepositoryByID(tx, c.Issue.RepoID)
|
||||
if err != nil {
|
||||
return errors.Newf("getRepositoryByID [%d]: %v", c.Issue.RepoID, err)
|
||||
}
|
||||
@@ -117,7 +119,7 @@ func (c *Comment) loadAttributes(e Engine) (err error) {
|
||||
}
|
||||
|
||||
if c.Attachments == nil {
|
||||
c.Attachments, err = getAttachmentsByCommentID(e, c.ID)
|
||||
c.Attachments, err = getAttachmentsByCommentID(tx, c.ID)
|
||||
if err != nil {
|
||||
return errors.Newf("getAttachmentsByCommentID [%d]: %v", c.ID, err)
|
||||
}
|
||||
@@ -127,7 +129,7 @@ func (c *Comment) loadAttributes(e Engine) (err error) {
|
||||
}
|
||||
|
||||
func (c *Comment) LoadAttributes() error {
|
||||
return c.loadAttributes(x)
|
||||
return c.loadAttributes(db)
|
||||
}
|
||||
|
||||
func (c *Comment) HTMLURL() string {
|
||||
@@ -163,9 +165,9 @@ func (c *Comment) EventTag() string {
|
||||
|
||||
// mailParticipants sends new comment emails to repository watchers
|
||||
// and mentioned people.
|
||||
func (c *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) (err error) {
|
||||
func (c *Comment) mailParticipants(tx *gorm.DB, opType ActionType, issue *Issue) (err error) {
|
||||
mentions := markup.FindAllMentions(c.Content)
|
||||
if err = updateIssueMentions(e, c.IssueID, mentions); err != nil {
|
||||
if err = updateIssueMentions(tx, c.IssueID, mentions); err != nil {
|
||||
return errors.Newf("UpdateIssueMentions [%d]: %v", c.IssueID, err)
|
||||
}
|
||||
|
||||
@@ -184,7 +186,7 @@ func (c *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) (e
|
||||
return nil
|
||||
}
|
||||
|
||||
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||
func createComment(tx *gorm.DB, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||
comment := &Comment{
|
||||
Type: opts.Type,
|
||||
PosterID: opts.Doer.ID,
|
||||
@@ -195,7 +197,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
Line: opts.LineNum,
|
||||
Content: opts.Content,
|
||||
}
|
||||
if _, err = e.Insert(comment); err != nil {
|
||||
if err = tx.Create(comment).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -216,14 +218,14 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
case CommentTypeComment:
|
||||
act.OpType = ActionCommentIssue
|
||||
|
||||
if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil {
|
||||
if err = tx.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check attachments
|
||||
attachments := make([]*Attachment, 0, len(opts.Attachments))
|
||||
for _, uuid := range opts.Attachments {
|
||||
attach, err := getAttachmentByUUID(e, uuid)
|
||||
attach, err := getAttachmentByUUID(tx, uuid)
|
||||
if err != nil {
|
||||
if IsErrAttachmentNotExist(err) {
|
||||
continue
|
||||
@@ -236,8 +238,10 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
for i := range attachments {
|
||||
attachments[i].IssueID = opts.Issue.ID
|
||||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = e.ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
if err = tx.Model(attachments[i]).Where("id = ?", attachments[i].ID).Updates(map[string]any{
|
||||
"issue_id": attachments[i].IssueID,
|
||||
"comment_id": attachments[i].CommentID,
|
||||
}).Error; err != nil {
|
||||
return nil, errors.Newf("update attachment [%d]: %v", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
@@ -249,9 +253,9 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", opts.Repo.ID)
|
||||
err = tx.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", opts.Repo.ID).Error
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", opts.Repo.ID)
|
||||
err = tx.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", opts.Repo.ID).Error
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -264,38 +268,38 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", opts.Repo.ID)
|
||||
err = tx.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", opts.Repo.ID).Error
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", opts.Repo.ID)
|
||||
err = tx.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", opts.Repo.ID).Error
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = e.Exec("UPDATE `issue` SET updated_unix = ? WHERE id = ?", time.Now().Unix(), opts.Issue.ID); err != nil {
|
||||
if err = tx.Exec("UPDATE `issue` SET updated_unix = ? WHERE id = ?", tx.NowFunc().Unix(), opts.Issue.ID).Error; err != nil {
|
||||
return nil, errors.Newf("update issue 'updated_unix': %v", err)
|
||||
}
|
||||
|
||||
// Notify watchers for whatever action comes in, ignore if no action type.
|
||||
if act.OpType > 0 {
|
||||
if err = notifyWatchers(e, act); err != nil {
|
||||
if err = notifyWatchers(tx, act); err != nil {
|
||||
log.Error("notifyWatchers: %v", err)
|
||||
}
|
||||
if err = comment.mailParticipants(e, act.OpType, opts.Issue); err != nil {
|
||||
if err = comment.mailParticipants(tx, act.OpType, opts.Issue); err != nil {
|
||||
log.Error("MailParticipants: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return comment, comment.loadAttributes(e)
|
||||
return comment, comment.loadAttributes(tx)
|
||||
}
|
||||
|
||||
func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
|
||||
func createStatusComment(tx *gorm.DB, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
|
||||
cmtType := CommentTypeClose
|
||||
if !issue.IsClosed {
|
||||
cmtType = CommentTypeReopen
|
||||
}
|
||||
return createComment(e, &CreateCommentOptions{
|
||||
return createComment(tx, &CreateCommentOptions{
|
||||
Type: cmtType,
|
||||
Doer: doer,
|
||||
Repo: repo,
|
||||
@@ -318,18 +322,12 @@ type CreateCommentOptions struct {
|
||||
|
||||
// CreateComment creates comment of issue or commit.
|
||||
func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
comment, err = createComment(sess, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return comment, sess.Commit()
|
||||
err = db.Transaction(func(tx *gorm.DB) error {
|
||||
var err error
|
||||
comment, err = createComment(tx, opts)
|
||||
return err
|
||||
})
|
||||
return comment, err
|
||||
}
|
||||
|
||||
// CreateIssueComment creates a plain issue comment.
|
||||
@@ -367,14 +365,12 @@ func CreateRefComment(doer *User, repo *Repository, issue *Issue, content, commi
|
||||
}
|
||||
|
||||
// Check if same reference from same commit has already existed.
|
||||
has, err := x.Get(&Comment{
|
||||
Type: CommentTypeCommitRef,
|
||||
IssueID: issue.ID,
|
||||
CommitSHA: commitSHA,
|
||||
})
|
||||
var count int64
|
||||
err := db.Model(new(Comment)).Where("type = ? AND issue_id = ? AND commit_sha = ?",
|
||||
CommentTypeCommitRef, issue.ID, commitSHA).Count(&count).Error
|
||||
if err != nil {
|
||||
return errors.Newf("check reference comment: %v", err)
|
||||
} else if has {
|
||||
} else if count > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -411,19 +407,20 @@ func (ErrCommentNotExist) NotFound() bool {
|
||||
// GetCommentByID returns the comment by given ID.
|
||||
func GetCommentByID(id int64) (*Comment, error) {
|
||||
c := new(Comment)
|
||||
has, err := x.Id(id).Get(c)
|
||||
err := db.Where("id = ?", id).First(c).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrCommentNotExist{args: map[string]any{"commentID": id}}
|
||||
}
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrCommentNotExist{args: map[string]any{"commentID": id}}
|
||||
}
|
||||
return c, c.LoadAttributes()
|
||||
}
|
||||
|
||||
// FIXME: use CommentList to improve performance.
|
||||
func loadCommentsAttributes(e Engine, comments []*Comment) (err error) {
|
||||
func loadCommentsAttributes(tx *gorm.DB, comments []*Comment) (err error) {
|
||||
for i := range comments {
|
||||
if err = comments[i].loadAttributes(e); err != nil {
|
||||
if err = comments[i].loadAttributes(tx); err != nil {
|
||||
return errors.Newf("loadAttributes [%d]: %v", comments[i].ID, err)
|
||||
}
|
||||
}
|
||||
@@ -431,53 +428,55 @@ func loadCommentsAttributes(e Engine, comments []*Comment) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCommentsByIssueIDSince(e Engine, issueID, since int64) ([]*Comment, error) {
|
||||
func getCommentsByIssueIDSince(tx *gorm.DB, issueID, since int64) ([]*Comment, error) {
|
||||
comments := make([]*Comment, 0, 10)
|
||||
sess := e.Where("issue_id = ?", issueID).Asc("created_unix")
|
||||
query := tx.Where("issue_id = ?", issueID).Order("created_unix ASC")
|
||||
if since > 0 {
|
||||
sess.And("updated_unix >= ?", since)
|
||||
query = query.Where("updated_unix >= ?", since)
|
||||
}
|
||||
|
||||
if err := sess.Find(&comments); err != nil {
|
||||
if err := query.Find(&comments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return comments, loadCommentsAttributes(e, comments)
|
||||
return comments, loadCommentsAttributes(tx, comments)
|
||||
}
|
||||
|
||||
func getCommentsByRepoIDSince(e Engine, repoID, since int64) ([]*Comment, error) {
|
||||
func getCommentsByRepoIDSince(tx *gorm.DB, repoID, since int64) ([]*Comment, error) {
|
||||
comments := make([]*Comment, 0, 10)
|
||||
sess := e.Where("issue.repo_id = ?", repoID).Join("INNER", "issue", "issue.id = comment.issue_id").Asc("comment.created_unix")
|
||||
query := tx.Joins("INNER JOIN issue ON issue.id = comment.issue_id").
|
||||
Where("issue.repo_id = ?", repoID).
|
||||
Order("comment.created_unix ASC")
|
||||
if since > 0 {
|
||||
sess.And("comment.updated_unix >= ?", since)
|
||||
query = query.Where("comment.updated_unix >= ?", since)
|
||||
}
|
||||
if err := sess.Find(&comments); err != nil {
|
||||
if err := query.Find(&comments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return comments, loadCommentsAttributes(e, comments)
|
||||
return comments, loadCommentsAttributes(tx, comments)
|
||||
}
|
||||
|
||||
func getCommentsByIssueID(e Engine, issueID int64) ([]*Comment, error) {
|
||||
return getCommentsByIssueIDSince(e, issueID, -1)
|
||||
func getCommentsByIssueID(tx *gorm.DB, issueID int64) ([]*Comment, error) {
|
||||
return getCommentsByIssueIDSince(tx, issueID, -1)
|
||||
}
|
||||
|
||||
// GetCommentsByIssueID returns all comments of an issue.
|
||||
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
|
||||
return getCommentsByIssueID(x, issueID)
|
||||
return getCommentsByIssueID(db, issueID)
|
||||
}
|
||||
|
||||
// GetCommentsByIssueIDSince returns a list of comments of an issue since a given time point.
|
||||
func GetCommentsByIssueIDSince(issueID, since int64) ([]*Comment, error) {
|
||||
return getCommentsByIssueIDSince(x, issueID, since)
|
||||
return getCommentsByIssueIDSince(db, issueID, since)
|
||||
}
|
||||
|
||||
// GetCommentsByRepoIDSince returns a list of comments for all issues in a repo since a given time point.
|
||||
func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
|
||||
return getCommentsByRepoIDSince(x, repoID, since)
|
||||
return getCommentsByRepoIDSince(db, repoID, since)
|
||||
}
|
||||
|
||||
// UpdateComment updates information of comment.
|
||||
func UpdateComment(doer *User, c *Comment, oldContent string) (err error) {
|
||||
if _, err = x.Id(c.ID).AllCols().Update(c); err != nil {
|
||||
if err = db.Model(c).Where("id = ?", c.ID).Updates(c).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -511,24 +510,21 @@ func DeleteCommentByID(doer *User, id int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.ID(comment.ID).Delete(new(Comment)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if comment.Type == CommentTypeComment {
|
||||
if _, err = sess.Exec("UPDATE `issue` SET num_comments = num_comments - 1 WHERE id = ?", comment.IssueID); err != nil {
|
||||
err = db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("id = ?", comment.ID).Delete(new(Comment)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return errors.Newf("commit: %v", err)
|
||||
if comment.Type == CommentTypeComment {
|
||||
if err := tx.Exec("UPDATE `issue` SET num_comments = num_comments - 1 WHERE id = ?", comment.IssueID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Newf("transaction: %v", err)
|
||||
}
|
||||
|
||||
_, err = DeleteAttachmentsByComment(comment.ID, true)
|
||||
|
||||
@@ -6,10 +6,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"gogs.io/gogs/internal/errutil"
|
||||
"gogs.io/gogs/internal/lazyregexp"
|
||||
@@ -53,13 +52,13 @@ func GetLabelTemplateFile(name string) ([][2]string, error) {
|
||||
// Label represents a label of repository for issues.
|
||||
type Label struct {
|
||||
ID int64
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
RepoID int64 `gorm:"index"`
|
||||
Name string
|
||||
Color string `xorm:"VARCHAR(7)"`
|
||||
Color string `gorm:"type:varchar(7)"`
|
||||
NumIssues int
|
||||
NumClosedIssues int
|
||||
NumOpenIssues int `xorm:"-" json:"-" gorm:"-"`
|
||||
IsChecked bool `xorm:"-" json:"-" gorm:"-"`
|
||||
NumOpenIssues int `gorm:"-" json:"-"`
|
||||
IsChecked bool `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
func (l *Label) APIFormat() *api.Label {
|
||||
@@ -97,8 +96,7 @@ func (l *Label) ForegroundColor() template.CSS {
|
||||
|
||||
// NewLabels creates new label(s) for a repository.
|
||||
func NewLabels(labels ...*Label) error {
|
||||
_, err := x.Insert(labels)
|
||||
return err
|
||||
return db.Create(labels).Error
|
||||
}
|
||||
|
||||
var _ errutil.NotFound = (*ErrLabelNotExist)(nil)
|
||||
@@ -123,20 +121,22 @@ func (ErrLabelNotExist) NotFound() bool {
|
||||
// getLabelOfRepoByName returns a label by Name in given repository.
|
||||
// If pass repoID as 0, then ORM will ignore limitation of repository
|
||||
// and can return arbitrary label with any valid ID.
|
||||
func getLabelOfRepoByName(e Engine, repoID int64, labelName string) (*Label, error) {
|
||||
func getLabelOfRepoByName(tx *gorm.DB, repoID int64, labelName string) (*Label, error) {
|
||||
if len(labelName) <= 0 {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID}}
|
||||
}
|
||||
|
||||
l := &Label{
|
||||
Name: labelName,
|
||||
RepoID: repoID,
|
||||
l := &Label{}
|
||||
query := tx.Where("name = ?", labelName)
|
||||
if repoID > 0 {
|
||||
query = query.Where("repo_id = ?", repoID)
|
||||
}
|
||||
has, err := e.Get(l)
|
||||
err := query.First(l).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID}}
|
||||
}
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID}}
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
@@ -144,54 +144,56 @@ func getLabelOfRepoByName(e Engine, repoID int64, labelName string) (*Label, err
|
||||
// getLabelInRepoByID returns a label by ID in given repository.
|
||||
// If pass repoID as 0, then ORM will ignore limitation of repository
|
||||
// and can return arbitrary label with any valid ID.
|
||||
func getLabelOfRepoByID(e Engine, repoID, labelID int64) (*Label, error) {
|
||||
func getLabelOfRepoByID(tx *gorm.DB, repoID, labelID int64) (*Label, error) {
|
||||
if labelID <= 0 {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID, "labelID": labelID}}
|
||||
}
|
||||
|
||||
l := &Label{
|
||||
ID: labelID,
|
||||
RepoID: repoID,
|
||||
l := &Label{}
|
||||
query := tx.Where("id = ?", labelID)
|
||||
if repoID > 0 {
|
||||
query = query.Where("repo_id = ?", repoID)
|
||||
}
|
||||
has, err := e.Get(l)
|
||||
err := query.First(l).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID, "labelID": labelID}}
|
||||
}
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrLabelNotExist{args: map[string]any{"repoID": repoID, "labelID": labelID}}
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// GetLabelByID returns a label by given ID.
|
||||
func GetLabelByID(id int64) (*Label, error) {
|
||||
return getLabelOfRepoByID(x, 0, id)
|
||||
return getLabelOfRepoByID(db, 0, id)
|
||||
}
|
||||
|
||||
// GetLabelOfRepoByID returns a label by ID in given repository.
|
||||
func GetLabelOfRepoByID(repoID, labelID int64) (*Label, error) {
|
||||
return getLabelOfRepoByID(x, repoID, labelID)
|
||||
return getLabelOfRepoByID(db, repoID, labelID)
|
||||
}
|
||||
|
||||
// GetLabelOfRepoByName returns a label by name in given repository.
|
||||
func GetLabelOfRepoByName(repoID int64, labelName string) (*Label, error) {
|
||||
return getLabelOfRepoByName(x, repoID, labelName)
|
||||
return getLabelOfRepoByName(db, repoID, labelName)
|
||||
}
|
||||
|
||||
// GetLabelsInRepoByIDs returns a list of labels by IDs in given repository,
|
||||
// it silently ignores label IDs that are not belong to the repository.
|
||||
func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
|
||||
labels := make([]*Label, 0, len(labelIDs))
|
||||
return labels, x.Where("repo_id = ?", repoID).In("id", tool.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
|
||||
return labels, db.Where("repo_id = ? AND id IN ?", repoID, labelIDs).Order("name ASC").Find(&labels).Error
|
||||
}
|
||||
|
||||
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
|
||||
func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
|
||||
labels := make([]*Label, 0, 10)
|
||||
return labels, x.Where("repo_id = ?", repoID).Asc("name").Find(&labels)
|
||||
return labels, db.Where("repo_id = ?", repoID).Order("name ASC").Find(&labels).Error
|
||||
}
|
||||
|
||||
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
|
||||
issueLabels, err := getIssueLabels(e, issueID)
|
||||
func getLabelsByIssueID(tx *gorm.DB, issueID int64) ([]*Label, error) {
|
||||
issueLabels, err := getIssueLabels(tx, issueID)
|
||||
if err != nil {
|
||||
return nil, errors.Newf("getIssueLabels: %v", err)
|
||||
} else if len(issueLabels) == 0 {
|
||||
@@ -204,22 +206,21 @@ func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
|
||||
}
|
||||
|
||||
labels := make([]*Label, 0, len(labelIDs))
|
||||
return labels, e.Where("id > 0").In("id", tool.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
|
||||
return labels, tx.Where("id > 0 AND id IN ?", labelIDs).Order("name ASC").Find(&labels).Error
|
||||
}
|
||||
|
||||
// GetLabelsByIssueID returns all labels that belong to given issue by ID.
|
||||
func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
|
||||
return getLabelsByIssueID(x, issueID)
|
||||
return getLabelsByIssueID(db, issueID)
|
||||
}
|
||||
|
||||
func updateLabel(e Engine, l *Label) error {
|
||||
_, err := e.ID(l.ID).AllCols().Update(l)
|
||||
return err
|
||||
func updateLabel(tx *gorm.DB, l *Label) error {
|
||||
return tx.Model(l).Where("id = ?", l.ID).Updates(l).Error
|
||||
}
|
||||
|
||||
// UpdateLabel updates label information.
|
||||
func UpdateLabel(l *Label) error {
|
||||
return updateLabel(x, l)
|
||||
return updateLabel(db, l)
|
||||
}
|
||||
|
||||
// DeleteLabel delete a label of given repository.
|
||||
@@ -232,19 +233,15 @@ func DeleteLabel(repoID, labelID int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.ID(labelID).Delete(new(Label)); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Where("label_id = ?", labelID).Delete(new(IssueLabel)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("id = ?", labelID).Delete(new(Label)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("label_id = ?", labelID).Delete(new(IssueLabel)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// .___ .____ ___. .__
|
||||
@@ -257,25 +254,26 @@ func DeleteLabel(repoID, labelID int64) error {
|
||||
// IssueLabel represents an issue-lable relation.
|
||||
type IssueLabel struct {
|
||||
ID int64
|
||||
IssueID int64 `xorm:"UNIQUE(s)"`
|
||||
LabelID int64 `xorm:"UNIQUE(s)"`
|
||||
IssueID int64 `gorm:"uniqueIndex:issue_label_unique"`
|
||||
LabelID int64 `gorm:"uniqueIndex:issue_label_unique"`
|
||||
}
|
||||
|
||||
func hasIssueLabel(e Engine, issueID, labelID int64) bool {
|
||||
has, _ := e.Where("issue_id = ? AND label_id = ?", issueID, labelID).Get(new(IssueLabel))
|
||||
return has
|
||||
func hasIssueLabel(tx *gorm.DB, issueID, labelID int64) bool {
|
||||
var count int64
|
||||
tx.Model(new(IssueLabel)).Where("issue_id = ? AND label_id = ?", issueID, labelID).Count(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
// HasIssueLabel returns true if issue has been labeled.
|
||||
func HasIssueLabel(issueID, labelID int64) bool {
|
||||
return hasIssueLabel(x, issueID, labelID)
|
||||
return hasIssueLabel(db, issueID, labelID)
|
||||
}
|
||||
|
||||
func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Insert(&IssueLabel{
|
||||
func newIssueLabel(tx *gorm.DB, issue *Issue, label *Label) (err error) {
|
||||
if err = tx.Create(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -284,7 +282,7 @@ func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
label.NumClosedIssues++
|
||||
}
|
||||
|
||||
if err = updateLabel(e, label); err != nil {
|
||||
if err = updateLabel(tx, label); err != nil {
|
||||
return errors.Newf("updateLabel: %v", err)
|
||||
}
|
||||
|
||||
@@ -298,26 +296,18 @@ func NewIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = newIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
return newIssueLabel(tx, issue, label)
|
||||
})
|
||||
}
|
||||
|
||||
func newIssueLabels(e *xorm.Session, issue *Issue, labels []*Label) (err error) {
|
||||
func newIssueLabels(tx *gorm.DB, issue *Issue, labels []*Label) (err error) {
|
||||
for i := range labels {
|
||||
if hasIssueLabel(e, issue.ID, labels[i].ID) {
|
||||
if hasIssueLabel(tx, issue.ID, labels[i].ID) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = newIssueLabel(e, issue, labels[i]); err != nil {
|
||||
if err = newIssueLabel(tx, issue, labels[i]); err != nil {
|
||||
return errors.Newf("newIssueLabel: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -327,34 +317,23 @@ func newIssueLabels(e *xorm.Session, issue *Issue, labels []*Label) (err error)
|
||||
|
||||
// NewIssueLabels creates a list of issue-label relations.
|
||||
func NewIssueLabels(issue *Issue, labels []*Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = newIssueLabels(sess, issue, labels); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
return newIssueLabels(tx, issue, labels)
|
||||
})
|
||||
}
|
||||
|
||||
func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
|
||||
func getIssueLabels(tx *gorm.DB, issueID int64) ([]*IssueLabel, error) {
|
||||
issueLabels := make([]*IssueLabel, 0, 10)
|
||||
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
|
||||
return issueLabels, tx.Where("issue_id = ?", issueID).Order("label_id ASC").Find(&issueLabels).Error
|
||||
}
|
||||
|
||||
// GetIssueLabels returns all issue-label relations of given issue by ID.
|
||||
func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
|
||||
return getIssueLabels(x, issueID)
|
||||
return getIssueLabels(db, issueID)
|
||||
}
|
||||
|
||||
func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Delete(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
func deleteIssueLabel(tx *gorm.DB, issue *Issue, label *Label) (err error) {
|
||||
if err = tx.Where("issue_id = ? AND label_id = ?", issue.ID, label.ID).Delete(&IssueLabel{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -362,7 +341,7 @@ func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues--
|
||||
}
|
||||
if err = updateLabel(e, label); err != nil {
|
||||
if err = updateLabel(tx, label); err != nil {
|
||||
return errors.Newf("updateLabel: %v", err)
|
||||
}
|
||||
|
||||
@@ -377,15 +356,7 @@ func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
|
||||
// DeleteIssueLabel deletes issue-label relation.
|
||||
func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = deleteIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
return deleteIssueLabel(tx, issue, label)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user