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 }