Public source validation / validate (push) Failing after 3m8s
80 lines
2.6 KiB
Go
80 lines
2.6 KiB
Go
package incident
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
func (r *Repository) UpdateOwner(ctx context.Context, id, owner string, expectedRevision int64) (Incident, error) {
|
|
if r == nil || r.Pool == nil {
|
|
return Incident{}, ErrUnavailable
|
|
}
|
|
if id == "" || expectedRevision < 1 || len(owner) > 160 || (owner != "" && !ownerUUIDPattern.MatchString(owner)) {
|
|
return Incident{}, ErrInvalid
|
|
}
|
|
var item Incident
|
|
ownerValue := any(nil)
|
|
if owner != "" {
|
|
ownerValue = owner
|
|
}
|
|
err := scanIncident(r.Pool.QueryRow(ctx, `UPDATE incidents SET owner_user_id=$1::uuid,revision=revision+1,updated_at=now() WHERE id=$2 AND revision=$3 RETURNING `+incidentColumns, ownerValue, id, expectedRevision), &item)
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
if _, getErr := r.Get(ctx, id); errors.Is(getErr, ErrNotFound) {
|
|
return Incident{}, ErrNotFound
|
|
}
|
|
return Incident{}, ErrConflict
|
|
}
|
|
if err != nil {
|
|
return Incident{}, mapError("update incident owner", err)
|
|
}
|
|
return r.Get(ctx, item.ID)
|
|
}
|
|
|
|
func (r *Repository) AddNote(ctx context.Context, incidentID, author, body string) (Note, error) {
|
|
if r == nil || r.Pool == nil {
|
|
return Note{}, ErrUnavailable
|
|
}
|
|
if incidentID == "" || author == "" || len(author) > 160 {
|
|
return Note{}, ErrInvalid
|
|
}
|
|
sanitized, err := SanitizeNote(body)
|
|
if err != nil {
|
|
return Note{}, err
|
|
}
|
|
var note Note
|
|
err = r.Pool.QueryRow(ctx, `INSERT INTO incident_notes (id,incident_id,author,body) VALUES ($1,$2,$3,$4) RETURNING id::text,incident_id::text,author,body,created_at`, newID(), incidentID, author, sanitized).Scan(¬e.ID, ¬e.IncidentID, ¬e.Author, ¬e.Body, ¬e.CreatedAt)
|
|
if err != nil {
|
|
return Note{}, mapError("add incident note", err)
|
|
}
|
|
return note, nil
|
|
}
|
|
|
|
func (r *Repository) ListNotes(ctx context.Context, incidentID string, limit int) ([]Note, error) {
|
|
if r == nil || r.Pool == nil {
|
|
return nil, ErrUnavailable
|
|
}
|
|
if incidentID == "" || limit < 1 || limit > 100 {
|
|
return nil, ErrInvalid
|
|
}
|
|
rows, err := r.Pool.Query(ctx, `SELECT id::text,incident_id::text,author,body,created_at FROM incident_notes WHERE incident_id=$1 ORDER BY created_at ASC,id ASC LIMIT $2`, incidentID, limit)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list incident notes: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
items := make([]Note, 0, limit)
|
|
for rows.Next() {
|
|
var note Note
|
|
if err := rows.Scan(¬e.ID, ¬e.IncidentID, ¬e.Author, ¬e.Body, ¬e.CreatedAt); err != nil {
|
|
return nil, fmt.Errorf("scan incident note: %w", err)
|
|
}
|
|
items = append(items, note)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|