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