Comments list performance optimization (#5305)

This commit is contained in:
2019-04-18 13:00:03 +08:00
committed by techknowlogick
parent 2262811e40
commit dd1acd7ce4
4 changed files with 555 additions and 42 deletions

View File

@ -272,6 +272,10 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
if err = issue.loadComments(e); err != nil {
return err
}
if err = CommentList(issue.Comments).loadAttributes(e); err != nil {
return err
}
if issue.isTimetrackerEnabled(e) {
if err = issue.loadTotalTimes(e); err != nil {
return err

View File

@ -154,6 +154,34 @@ func (c *Comment) LoadIssue() (err error) {
return
}
func (c *Comment) loadPoster(e Engine) (err error) {
if c.Poster != nil {
return nil
}
c.Poster, err = getUserByID(e, c.PosterID)
if err != nil {
if IsErrUserNotExist(err) {
c.PosterID = -1
c.Poster = NewGhostUser()
} else {
log.Error("getUserByID[%d]: %v", c.ID, err)
}
}
return err
}
func (c *Comment) loadAttachments(e Engine) (err error) {
if len(c.Attachments) > 0 {
return
}
c.Attachments, err = getAttachmentsByCommentID(e, c.ID)
if err != nil {
log.Error("getAttachmentsByCommentID[%d]: %v", c.ID, err)
}
return err
}
// AfterDelete is invoked from XORM after the object is deleted.
func (c *Comment) AfterDelete() {
if c.ID <= 0 {
@ -997,32 +1025,6 @@ func FindComments(opts FindCommentsOptions) ([]*Comment, error) {
return findComments(x, opts)
}
// GetCommentsByIssueID returns all comments of an issue.
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
return findComments(x, FindCommentsOptions{
IssueID: issueID,
Type: CommentTypeUnknown,
})
}
// GetCommentsByIssueIDSince returns a list of comments of an issue since a given time point.
func GetCommentsByIssueIDSince(issueID, since int64) ([]*Comment, error) {
return findComments(x, FindCommentsOptions{
IssueID: issueID,
Type: CommentTypeUnknown,
Since: 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 findComments(x, FindCommentsOptions{
RepoID: repoID,
Type: CommentTypeUnknown,
Since: since,
})
}
// UpdateComment updates information of comment.
func UpdateComment(doer *User, c *Comment, oldContent string) error {
if _, err := x.ID(c.ID).AllCols().Update(c); err != nil {
@ -1039,6 +1041,9 @@ func UpdateComment(doer *User, c *Comment, oldContent string) error {
if err := c.Issue.LoadAttributes(); err != nil {
return err
}
if err := c.loadPoster(x); err != nil {
return err
}
mode, _ := AccessLevel(doer, c.Issue.Repo)
if err := PrepareWebhooks(c.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
@ -1087,6 +1092,7 @@ func DeleteComment(doer *User, comment *Comment) error {
if err := sess.Commit(); err != nil {
return err
}
sess.Close()
if err := comment.LoadPoster(); err != nil {
return err
@ -1098,6 +1104,9 @@ func DeleteComment(doer *User, comment *Comment) error {
if err := comment.Issue.LoadAttributes(); err != nil {
return err
}
if err := comment.loadPoster(x); err != nil {
return err
}
mode, _ := AccessLevel(doer, comment.Issue.Repo)
@ -1154,6 +1163,11 @@ func fetchCodeCommentsByReview(e Engine, issue *Issue, currentUser *User, review
if err := issue.loadRepo(e); err != nil {
return nil, err
}
if err := CommentList(comments).loadPosters(e); err != nil {
return nil, err
}
// Find all reviews by ReviewID
reviews := make(map[int64]*Review)
var ids = make([]int64, 0, len(comments))

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,7 @@ func ListIssueComments(ctx *context.APIContext) {
ctx.Error(500, "GetRawIssueByIndex", err)
return
}
issue.Repo = ctx.Repo.Repository
comments, err := models.FindComments(models.FindCommentsOptions{
IssueID: issue.ID,
@ -64,16 +65,18 @@ func ListIssueComments(ctx *context.APIContext) {
Type: models.CommentTypeComment,
})
if err != nil {
ctx.Error(500, "GetCommentsByIssueIDSince", err)
ctx.Error(500, "FindComments", err)
return
}
if err := models.CommentList(comments).LoadPosters(); err != nil {
ctx.Error(500, "LoadPosters", err)
return
}
apiComments := make([]*api.Comment, len(comments))
if err = models.CommentList(comments).LoadPosters(); err != nil {
ctx.Error(500, "LoadPosters", err)
return
}
for i := range comments {
for i, comment := range comments {
comment.Issue = issue
apiComments[i] = comments[i].APIFormat()
}
ctx.JSON(200, &apiComments)
@ -115,7 +118,7 @@ func ListRepoIssueComments(ctx *context.APIContext) {
Type: models.CommentTypeComment,
})
if err != nil {
ctx.Error(500, "GetCommentsByRepoIDSince", err)
ctx.Error(500, "FindComments", err)
return
}
@ -125,6 +128,18 @@ func ListRepoIssueComments(ctx *context.APIContext) {
}
apiComments := make([]*api.Comment, len(comments))
if err := models.CommentList(comments).LoadIssues(); err != nil {
ctx.Error(500, "LoadIssues", err)
return
}
if err := models.CommentList(comments).LoadPosters(); err != nil {
ctx.Error(500, "LoadPosters", err)
return
}
if _, err := models.CommentList(comments).Issues().LoadRepositories(); err != nil {
ctx.Error(500, "LoadRepositories", err)
return
}
for i := range comments {
apiComments[i] = comments[i].APIFormat()
}