You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
3.4 KiB
Go

package database
import (
"context"
"database/sql"
"fmt"
)
// QuestionRepository handles question operations
type QuestionRepository struct {
client *Client
}
// NewQuestionRepository creates a new question repository
func NewQuestionRepository(client *Client) *QuestionRepository {
return &QuestionRepository{client: client}
}
// Create creates a new question
func (r *QuestionRepository) Create(ctx context.Context, question *Question) error {
query := `
INSERT INTO questions (id, theme, text, answer, hint, difficulty, is_active, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
`
_, err := r.client.db.ExecContext(ctx, query,
question.ID,
question.Theme,
question.Text,
question.Answer,
question.Hint,
question.Difficulty,
question.IsActive,
question.CreatedAt,
question.UpdatedAt,
)
return err
}
// GetByID retrieves a question by ID
func (r *QuestionRepository) GetByID(ctx context.Context, id string) (*Question, error) {
query := `
SELECT id, theme, text, answer, hint, difficulty, is_active, created_at, updated_at
FROM questions
WHERE id = $1
`
var question Question
err := r.client.db.QueryRowContext(ctx, query, id).Scan(
&question.ID,
&question.Theme,
&question.Text,
&question.Answer,
&question.Hint,
&question.Difficulty,
&question.IsActive,
&question.CreatedAt,
&question.UpdatedAt,
)
if err != nil {
if err == sql.ErrNoRows {
return nil, fmt.Errorf("question not found: %s", id)
}
return nil, err
}
return &question, nil
}
// GetByTheme retrieves questions by theme
func (r *QuestionRepository) GetByTheme(ctx context.Context, theme string) ([]*Question, error) {
query := `
SELECT id, theme, text, answer, hint, difficulty, is_active, created_at, updated_at
FROM questions
WHERE theme = $1 AND is_active = true
ORDER BY created_at DESC
`
rows, err := r.client.db.QueryContext(ctx, query, theme)
if err != nil {
return nil, err
}
defer rows.Close()
var questions []*Question
for rows.Next() {
var question Question
err := rows.Scan(
&question.ID,
&question.Theme,
&question.Text,
&question.Answer,
&question.Hint,
&question.Difficulty,
&question.IsActive,
&question.CreatedAt,
&question.UpdatedAt,
)
if err != nil {
return nil, err
}
questions = append(questions, &question)
}
return questions, rows.Err()
}
// GetRandom retrieves a random question
func (r *QuestionRepository) GetRandom(ctx context.Context, theme string, difficulty string) (*Question, error) {
query := `
SELECT id, theme, text, answer, hint, difficulty, is_active, created_at, updated_at
FROM questions
WHERE is_active = true
`
args := []interface{}{}
argIndex := 1
if theme != "" {
query += fmt.Sprintf(" AND theme = $%d", argIndex)
args = append(args, theme)
argIndex++
}
if difficulty != "" {
query += fmt.Sprintf(" AND difficulty = $%d", argIndex)
args = append(args, difficulty)
argIndex++
}
query += " ORDER BY RANDOM() LIMIT 1"
var question Question
err := r.client.db.QueryRowContext(ctx, query, args...).Scan(
&question.ID,
&question.Theme,
&question.Text,
&question.Answer,
&question.Hint,
&question.Difficulty,
&question.IsActive,
&question.CreatedAt,
&question.UpdatedAt,
)
if err != nil {
if err == sql.ErrNoRows {
return nil, fmt.Errorf("no questions found for theme: %s, difficulty: %s", theme, difficulty)
}
return nil, err
}
return &question, nil
}