mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-04 03:35:05 +02:00
Per @lunny's feedback, rework to reuse the existing Comment table instead of a standalone commit_comment table. The junction table (commit_comment) now only stores repo_id, commit_sha, comment_id. Actual comment data (content, tree_path, line, patch, poster) lives in the Comment table with Type = CommentTypeCommitComment (39). This gives commit comments reactions, attachments, and all existing comment infrastructure for free.
140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package issues
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.gitea.io/gitea/models/db"
|
|
)
|
|
|
|
// CommitComment is a junction table linking a commit (repo + SHA) to
|
|
// a Comment entry. The comment content, tree_path, line, poster, etc.
|
|
// are stored in the Comment table with Type = CommentTypeCommitComment.
|
|
type CommitComment struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
RepoID int64 `xorm:"INDEX NOT NULL"`
|
|
CommitSHA string `xorm:"VARCHAR(64) INDEX NOT NULL"`
|
|
CommentID int64 `xorm:"UNIQUE NOT NULL"`
|
|
}
|
|
|
|
func init() {
|
|
db.RegisterModel(new(CommitComment))
|
|
}
|
|
|
|
// FileCommitComments holds commit comments for a single file,
|
|
// split by side (left = old, right = new) with int keys matching DiffLine indices.
|
|
type FileCommitComments struct {
|
|
Left map[int][]*Comment
|
|
Right map[int][]*Comment
|
|
}
|
|
|
|
// CommitCommentsForDiff maps file paths to their commit comments.
|
|
type CommitCommentsForDiff map[string]*FileCommitComments
|
|
|
|
// FindCommitCommentsByCommitSHA returns all comments for a given commit in a repo.
|
|
func FindCommitCommentsByCommitSHA(ctx context.Context, repoID int64, commitSHA string) ([]*Comment, error) {
|
|
var refs []CommitComment
|
|
if err := db.GetEngine(ctx).
|
|
Where("repo_id = ? AND commit_sha = ?", repoID, commitSHA).
|
|
Find(&refs); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(refs) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
commentIDs := make([]int64, 0, len(refs))
|
|
for _, ref := range refs {
|
|
commentIDs = append(commentIDs, ref.CommentID)
|
|
}
|
|
|
|
comments := make([]*Comment, 0, len(commentIDs))
|
|
if err := db.GetEngine(ctx).
|
|
In("id", commentIDs).
|
|
OrderBy("created_unix ASC").
|
|
Find(&comments); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, c := range comments {
|
|
if err := c.LoadPoster(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return comments, nil
|
|
}
|
|
|
|
// FindCommitCommentsForDiff returns comments grouped by path and side for rendering in a diff view.
|
|
func FindCommitCommentsForDiff(ctx context.Context, repoID int64, commitSHA string) (CommitCommentsForDiff, error) {
|
|
comments, err := FindCommitCommentsByCommitSHA(ctx, repoID, commitSHA)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make(CommitCommentsForDiff)
|
|
for _, c := range comments {
|
|
fcc, ok := result[c.TreePath]
|
|
if !ok {
|
|
fcc = &FileCommitComments{
|
|
Left: make(map[int][]*Comment),
|
|
Right: make(map[int][]*Comment),
|
|
}
|
|
result[c.TreePath] = fcc
|
|
}
|
|
if c.Line < 0 {
|
|
idx := int(-c.Line)
|
|
fcc.Left[idx] = append(fcc.Left[idx], c)
|
|
} else {
|
|
idx := int(c.Line)
|
|
fcc.Right[idx] = append(fcc.Right[idx], c)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// CreateCommitComment creates a Comment with type CommitComment and a
|
|
// corresponding CommitComment junction record, within a transaction.
|
|
func CreateCommitComment(ctx context.Context, repoID int64, commitSHA string, comment *Comment) error {
|
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
if _, err := db.GetEngine(ctx).Insert(comment); err != nil {
|
|
return err
|
|
}
|
|
|
|
ref := &CommitComment{
|
|
RepoID: repoID,
|
|
CommitSHA: commitSHA,
|
|
CommentID: comment.ID,
|
|
}
|
|
_, err := db.GetEngine(ctx).Insert(ref)
|
|
return err
|
|
})
|
|
}
|
|
|
|
// DeleteCommitComment deletes both the junction record and the Comment entry.
|
|
func DeleteCommitComment(ctx context.Context, commentID int64) error {
|
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
if _, err := db.GetEngine(ctx).Where("comment_id = ?", commentID).Delete(&CommitComment{}); err != nil {
|
|
return err
|
|
}
|
|
_, err := db.GetEngine(ctx).ID(commentID).Delete(&Comment{})
|
|
return err
|
|
})
|
|
}
|
|
|
|
// GetCommitCommentByID returns a commit comment by loading the Comment entry.
|
|
func GetCommitCommentByID(ctx context.Context, commentID int64) (*Comment, error) {
|
|
c := &Comment{}
|
|
has, err := db.GetEngine(ctx).ID(commentID).Get(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !has {
|
|
return nil, db.ErrNotExist{Resource: "CommitComment", ID: commentID}
|
|
}
|
|
return c, nil
|
|
}
|