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 } }