onasty/internal/store/psql/noterepo/noterepo.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
package noterepo
import (
"context"
"errors"
"github.com/gofrs/uuid/v5"
"github.com/henvic/pgq"
"github.com/jackc/pgx/v5"
"github.com/olexsmir/onasty/internal/dtos"
"github.com/olexsmir/onasty/internal/models"
"github.com/olexsmir/onasty/internal/store/psqlutil"
)
type NoteStorer interface {
Create(ctx context.Context, inp dtos.CreateNoteDTO) error
GetBySlug(ctx context.Context, slug dtos.NoteSlugDTO) (dtos.NoteDTO, error)
DeleteBySlug(ctx context.Context, slug dtos.NoteSlugDTO) error
SetAuthorIDBySlug(ctx context.Context, slug dtos.NoteSlugDTO, authorID uuid.UUID) error
}
var _ NoteStorer = (*NoteRepo)(nil)
type NoteRepo struct {
db *psqlutil.DB
}
func New(db *psqlutil.DB) *NoteRepo {
return &NoteRepo{db}
}
func (s *NoteRepo) Create(ctx context.Context, inp dtos.CreateNoteDTO) error {
query, args, err := pgq.
Insert("notes").
Columns("content", "slug", "burn_before_expiration ", "created_at", "expires_at").
Values(inp.Content, inp.Slug, inp.BurnBeforeExpiration, inp.CreatedAt, inp.ExpiresAt).
SQL()
if err != nil {
return err
}
_, err = s.db.Exec(ctx, query, args...)
if psqlutil.IsDuplicateErr(err) {
return models.ErrNoteSlugIsAlreadyInUse
}
return err
}
func (s *NoteRepo) GetBySlug(ctx context.Context, slug dtos.NoteSlugDTO) (dtos.NoteDTO, error) {
query, args, err := pgq.
Select("content", "slug", "burn_before_expiration", "created_at", "expires_at").
From("notes").
Where("slug = ?", slug).
SQL()
if err != nil {
return dtos.NoteDTO{}, err
}
var note dtos.NoteDTO
err = s.db.QueryRow(ctx, query, args...).
Scan(¬e.Content, ¬e.Slug, ¬e.BurnBeforeExpiration, ¬e.CreatedAt, ¬e.ExpiresAt)
if errors.Is(err, pgx.ErrNoRows) {
return dtos.NoteDTO{}, models.ErrNoteNotFound
}
return note, err
}
func (s *NoteRepo) DeleteBySlug(ctx context.Context, slug dtos.NoteSlugDTO) error {
query, args, err := pgq.
Delete("notes").
Where(pgq.Eq{"slug": slug}).
SQL()
if err != nil {
return err
}
_, err = s.db.Exec(ctx, query, args...)
if errors.Is(err, pgx.ErrNoRows) {
return models.ErrNoteNotFound
}
return err
}
func (s *NoteRepo) SetAuthorIDBySlug(
ctx context.Context,
slug dtos.NoteSlugDTO,
authorID uuid.UUID,
) error {
tx, err := s.db.Begin(ctx)
if err != nil {
return err
}
defer tx.Rollback(ctx) //nolint:errcheck
var noteID uuid.UUID
err = tx.QueryRow(ctx, "select id from notes where slug = $1", slug).Scan(¬eID)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return models.ErrNoteNotFound
}
return err
}
_, err = tx.Exec(
ctx,
"insert into notes_authors (note_id, user_id) values ($1, $2)",
noteID, authorID,
)
if err != nil {
return err
}
return tx.Commit(ctx)
}
|