CreateIssueComments creates one or more issue comments. For a single comment, it returns the created comment with UID, CreatedAt, and UpdatedAt filled in. For multiple comments, it performs a batch insert and returns nil.
(ctx context.Context, creator string, creates ...*IssueCommentMessage)
| 127 | // For a single comment, it returns the created comment with UID, CreatedAt, and UpdatedAt filled in. |
| 128 | // For multiple comments, it performs a batch insert and returns nil. |
| 129 | func (s *Store) CreateIssueComments(ctx context.Context, creator string, creates ...*IssueCommentMessage) (*IssueCommentMessage, error) { |
| 130 | if len(creates) == 0 { |
| 131 | return nil, nil |
| 132 | } |
| 133 | |
| 134 | // Prepare all payloads. |
| 135 | projectIDs := make([]string, 0, len(creates)) |
| 136 | issueIDs := make([]int64, 0, len(creates)) |
| 137 | payloads := make([][]byte, 0, len(creates)) |
| 138 | for _, create := range creates { |
| 139 | payload, err := protojson.Marshal(create.Payload) |
| 140 | if err != nil { |
| 141 | return nil, errors.Wrapf(err, "failed to marshal payload") |
| 142 | } |
| 143 | projectIDs = append(projectIDs, create.ProjectID) |
| 144 | issueIDs = append(issueIDs, create.IssueUID) |
| 145 | payloads = append(payloads, payload) |
| 146 | } |
| 147 | |
| 148 | // Use UNNEST to insert all comments in one query. |
| 149 | q := qb.Q().Space(` |
| 150 | INSERT INTO issue_comment (creator, project, issue_id, payload) |
| 151 | SELECT ?, unnest(?::TEXT[]), unnest(?::INT[]), unnest(?::JSONB[]) |
| 152 | `, creator, projectIDs, issueIDs, payloads) |
| 153 | |
| 154 | // For single comment, use RETURNING to get the created comment details. |
| 155 | if len(creates) == 1 { |
| 156 | q.Space("RETURNING resource_id, created_at, updated_at") |
| 157 | query, args, err := q.ToSQL() |
| 158 | if err != nil { |
| 159 | return nil, errors.Wrapf(err, "failed to build sql") |
| 160 | } |
| 161 | |
| 162 | create := creates[0] |
| 163 | if err := s.GetDB().QueryRowContext(ctx, query, args...).Scan(&create.ResourceID, &create.CreatedAt, &create.UpdatedAt); err != nil { |
| 164 | return nil, errors.Wrapf(err, "failed to insert") |
| 165 | } |
| 166 | create.CreatorEmail = creator |
| 167 | return create, nil |
| 168 | } |
| 169 | |
| 170 | // For multiple comments, just execute without RETURNING. |
| 171 | query, args, err := q.ToSQL() |
| 172 | if err != nil { |
| 173 | return nil, errors.Wrapf(err, "failed to build sql") |
| 174 | } |
| 175 | |
| 176 | if _, err := s.GetDB().ExecContext(ctx, query, args...); err != nil { |
| 177 | return nil, errors.Wrapf(err, "failed to batch insert comments") |
| 178 | } |
| 179 | |
| 180 | return nil, nil |
| 181 | } |
| 182 | |
| 183 | func (s *Store) UpdateIssueComment(ctx context.Context, patch *UpdateIssueCommentMessage) error { |
| 184 | q := qb.Q().Space("UPDATE issue_comment SET updated_at = ?", time.Now()) |
no test coverage detected