code.gitea.io/gitea@v1.21.7/models/issues/issue_user.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package issues
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	repo_model "code.gitea.io/gitea/models/repo"
    12  )
    13  
    14  // IssueUser represents an issue-user relation.
    15  type IssueUser struct {
    16  	ID          int64 `xorm:"pk autoincr"`
    17  	UID         int64 `xorm:"INDEX"` // User ID.
    18  	IssueID     int64 `xorm:"INDEX"`
    19  	IsRead      bool
    20  	IsMentioned bool
    21  }
    22  
    23  func init() {
    24  	db.RegisterModel(new(IssueUser))
    25  }
    26  
    27  // NewIssueUsers inserts an issue related users
    28  func NewIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error {
    29  	assignees, err := repo_model.GetRepoAssignees(ctx, repo)
    30  	if err != nil {
    31  		return fmt.Errorf("getAssignees: %w", err)
    32  	}
    33  
    34  	// Poster can be anyone, append later if not one of assignees.
    35  	isPosterAssignee := false
    36  
    37  	// Leave a seat for poster itself to append later, but if poster is one of assignee
    38  	// and just waste 1 unit is cheaper than re-allocate memory once.
    39  	issueUsers := make([]*IssueUser, 0, len(assignees)+1)
    40  	for _, assignee := range assignees {
    41  		issueUsers = append(issueUsers, &IssueUser{
    42  			IssueID: issue.ID,
    43  			UID:     assignee.ID,
    44  		})
    45  		isPosterAssignee = isPosterAssignee || assignee.ID == issue.PosterID
    46  	}
    47  	if !isPosterAssignee {
    48  		issueUsers = append(issueUsers, &IssueUser{
    49  			IssueID: issue.ID,
    50  			UID:     issue.PosterID,
    51  		})
    52  	}
    53  
    54  	return db.Insert(ctx, issueUsers)
    55  }
    56  
    57  // UpdateIssueUserByRead updates issue-user relation for reading.
    58  func UpdateIssueUserByRead(ctx context.Context, uid, issueID int64) error {
    59  	_, err := db.GetEngine(ctx).Exec("UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=?", true, uid, issueID)
    60  	return err
    61  }
    62  
    63  // UpdateIssueUsersByMentions updates issue-user pairs by mentioning.
    64  func UpdateIssueUsersByMentions(ctx context.Context, issueID int64, uids []int64) error {
    65  	for _, uid := range uids {
    66  		iu := &IssueUser{
    67  			UID:     uid,
    68  			IssueID: issueID,
    69  		}
    70  		has, err := db.GetEngine(ctx).Get(iu)
    71  		if err != nil {
    72  			return err
    73  		}
    74  
    75  		iu.IsMentioned = true
    76  		if has {
    77  			_, err = db.GetEngine(ctx).ID(iu.ID).Cols("is_mentioned").Update(iu)
    78  		} else {
    79  			_, err = db.GetEngine(ctx).Insert(iu)
    80  		}
    81  		if err != nil {
    82  			return err
    83  		}
    84  	}
    85  	return nil
    86  }
    87  
    88  // GetIssueMentionIDs returns all mentioned user IDs of an issue.
    89  func GetIssueMentionIDs(ctx context.Context, issueID int64) ([]int64, error) {
    90  	var ids []int64
    91  	return ids, db.GetEngine(ctx).Table(IssueUser{}).
    92  		Where("issue_id=?", issueID).
    93  		And("is_mentioned=?", true).
    94  		Select("uid").
    95  		Find(&ids)
    96  }