78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
|
|
package interview
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
||
|
|
)
|
||
|
|
|
||
|
|
type PostgresStore struct {
|
||
|
|
pool *pgxpool.Pool
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewPostgresStore(pool *pgxpool.Pool) *PostgresStore {
|
||
|
|
return &PostgresStore{pool: pool}
|
||
|
|
}
|
||
|
|
|
||
|
|
func toJSON(v any) string {
|
||
|
|
b, _ := json.Marshal(v)
|
||
|
|
return string(b)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *PostgresStore) Create(session Session) (Session, error) {
|
||
|
|
_, err := s.pool.Exec(context.Background(),
|
||
|
|
`INSERT INTO interview_sessions (id, user_id, target_role, stack, interview_timeline, questions, answers, created_at)
|
||
|
|
VALUES ($1, $2, $3, $4::jsonb, $5, $6::jsonb, $7::jsonb, $8)
|
||
|
|
ON CONFLICT (id) DO UPDATE SET
|
||
|
|
user_id = EXCLUDED.user_id,
|
||
|
|
target_role = EXCLUDED.target_role,
|
||
|
|
stack = EXCLUDED.stack,
|
||
|
|
interview_timeline = EXCLUDED.interview_timeline,
|
||
|
|
questions = EXCLUDED.questions,
|
||
|
|
answers = EXCLUDED.answers,
|
||
|
|
created_at = EXCLUDED.created_at`,
|
||
|
|
session.ID, session.UserID, session.TargetRole, toJSON(session.Stack),
|
||
|
|
session.InterviewTimeline, toJSON(session.Questions), toJSON(session.Answers), session.CreatedAt,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
return Session{}, fmt.Errorf("insert session: %w", err)
|
||
|
|
}
|
||
|
|
return session, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *PostgresStore) Get(id string) (Session, error) {
|
||
|
|
var session Session
|
||
|
|
var stackJSON, questionsJSON, answersJSON string
|
||
|
|
|
||
|
|
err := s.pool.QueryRow(context.Background(),
|
||
|
|
`SELECT id, user_id, target_role, stack, interview_timeline, questions, answers, created_at
|
||
|
|
FROM interview_sessions WHERE id = $1`, id,
|
||
|
|
).Scan(&session.ID, &session.UserID, &session.TargetRole, &stackJSON,
|
||
|
|
&session.InterviewTimeline, &questionsJSON, &answersJSON, &session.CreatedAt)
|
||
|
|
if err != nil {
|
||
|
|
return Session{}, ErrSessionNotFound
|
||
|
|
}
|
||
|
|
|
||
|
|
json.Unmarshal([]byte(stackJSON), &session.Stack)
|
||
|
|
json.Unmarshal([]byte(questionsJSON), &session.Questions)
|
||
|
|
json.Unmarshal([]byte(answersJSON), &session.Answers)
|
||
|
|
return session, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *PostgresStore) Update(session Session) (Session, error) {
|
||
|
|
_, err := s.pool.Exec(context.Background(),
|
||
|
|
`UPDATE interview_sessions SET
|
||
|
|
user_id = $2, target_role = $3, stack = $4::jsonb, interview_timeline = $5,
|
||
|
|
questions = $6::jsonb, answers = $7::jsonb, created_at = $8
|
||
|
|
WHERE id = $1`,
|
||
|
|
session.ID, session.UserID, session.TargetRole, toJSON(session.Stack),
|
||
|
|
session.InterviewTimeline, toJSON(session.Questions), toJSON(session.Answers), session.CreatedAt,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
return Session{}, fmt.Errorf("update session: %w", err)
|
||
|
|
}
|
||
|
|
return session, nil
|
||
|
|
}
|