sessions/internal/bundb/api_key.go

77 lines
1.7 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 APIKey struct {
db *bun.DB
}
func NewAPIKey(db *bun.DB) *APIKey {
return &APIKey{db: db}
}
func (a *APIKey) Create(ctx context.Context, params domain.CreateAPIKeyParams) (domain.APIKey, error) {
apiKey := model.NewAPIKey(params)
if _, err := a.db.NewInsert().
Model(&apiKey).
Returning("*").
Exec(ctx); err != nil {
return domain.APIKey{}, fmt.Errorf(
"something went wrong while inserting api key into the db: %w",
mapCreateAPIKeyError(err, params),
)
}
return apiKey.ToDomain(), nil
}
func (a *APIKey) Get(ctx context.Context, key string) (domain.APIKey, error) {
var ak model.APIKey
if err := a.db.NewSelect().
Model(&ak).
Where("key = ?", key).
Scan(ctx); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.APIKey{}, domain.APIKeyNotFoundError{Key: key}
}
return domain.APIKey{}, fmt.Errorf(
"something went wrong while selecting api key (key=%s) from the db: %w",
key,
err,
)
}
return ak.ToDomain(), nil
}
func mapCreateAPIKeyError(err error, params domain.CreateAPIKeyParams) 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 == "api_keys_user_id_fkey":
return domain.UserDoesNotExistError{
ID: params.UserID(),
}
default:
return err
}
}