sessions/internal/bundb/session.go
Dawid Wysokiński 786cc60e38
All checks were successful
continuous-integration/drone/push Build is passing
feat: add a new REST endpoint - GET /api/v1/user/sessions/:server (#14)
Reviewed-on: #14
2022-11-25 05:55:31 +00:00

82 lines
1.9 KiB
Go

package bundb
import (
"context"
"database/sql"
"errors"
"fmt"
"gitea.dwysokinski.me/twhelp/sessions/internal/bundb/internal/model"
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
"github.com/jackc/pgerrcode"
"github.com/uptrace/bun"
"github.com/uptrace/bun/driver/pgdriver"
)
type Session struct {
db *bun.DB
}
func NewSession(db *bun.DB) *Session {
return &Session{db: db}
}
func (s *Session) CreateOrUpdate(ctx context.Context, params domain.CreateSessionParams) (domain.Session, error) {
sess := model.NewSession(params)
if _, err := s.db.NewInsert().
Model(&sess).
On("CONFLICT ON CONSTRAINT sessions_user_id_server_key_key DO UPDATE").
Set("sid = EXCLUDED.sid").
Set("updated_at = EXCLUDED.updated_at").
Returning("*").
Exec(ctx); err != nil {
return domain.Session{}, fmt.Errorf(
"something went wrong while inserting session into the db: %w",
mapCreateSessionError(err, params),
)
}
return sess.ToDomain(), nil
}
func (s *Session) Get(ctx context.Context, userID int64, serverKey string) (domain.Session, error) {
var sess model.Session
if err := s.db.NewSelect().
Model(&sess).
Where("user_id = ?", userID).
Where("server_key = ?", serverKey).
Scan(ctx); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.Session{}, domain.SessionNotFoundError{ServerKey: serverKey}
}
return domain.Session{}, fmt.Errorf(
"something went wrong while selecting sess (userID=%d,serverKey=%s) from the db: %w",
userID,
serverKey,
err,
)
}
return sess.ToDomain(), nil
}
func mapCreateSessionError(err error, params domain.CreateSessionParams) error {
var pgError pgdriver.Error
if !errors.As(err, &pgError) {
return err
}
code := pgError.Field('C')
constraint := pgError.Field('n')
switch {
case code == pgerrcode.ForeignKeyViolation && constraint == "sessions_user_id_fkey":
return domain.UserDoesNotExistError{
ID: params.UserID(),
}
default:
return err
}
}