feat(tester): add solution endpoints
add CreateSolution&GetSolution&ListSolutions endpoints
This commit is contained in:
parent
af6e0b89f6
commit
ef696d2836
9 changed files with 316 additions and 8 deletions
|
@ -2,8 +2,10 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ContestRepository struct {
|
||||
|
@ -247,3 +249,145 @@ func (r *ContestRepository) UpdateParticipant(ctx context.Context, id int32, par
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
readSolutionQuery = "SELECT * FROM solutions WHERE id = ?"
|
||||
)
|
||||
|
||||
func (r *ContestRepository) ReadSolution(ctx context.Context, id int32) (*models.Solution, error) {
|
||||
const op = "ContestRepository.ReadSolution"
|
||||
|
||||
query := r.db.Rebind(readSolutionQuery)
|
||||
var solution models.Solution
|
||||
err := r.db.GetContext(ctx, &solution, query, id)
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
return &solution, nil
|
||||
}
|
||||
|
||||
const (
|
||||
createSolutionQuery = `INSERT INTO solutions (task_id, participant_id, language, penalty, solution)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING id`
|
||||
)
|
||||
|
||||
func (r *ContestRepository) CreateSolution(ctx context.Context, creation *models.SolutionCreation) (int32, error) {
|
||||
const op = "ContestRepository.CreateSolution"
|
||||
|
||||
query := r.db.Rebind(createSolutionQuery)
|
||||
|
||||
rows, err := r.db.QueryxContext(ctx,
|
||||
query,
|
||||
creation.TaskId,
|
||||
creation.ParticipantId,
|
||||
creation.Language,
|
||||
creation.Penalty,
|
||||
creation.Solution,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
var id int32
|
||||
rows.Next()
|
||||
err = rows.Scan(&id)
|
||||
if err != nil {
|
||||
return 0, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (r *ContestRepository) ListSolutions(ctx context.Context, filters models.SolutionsFilter) ([]*models.SolutionsListItem, int32, error) {
|
||||
const op = "ContestRepository.ListSolutions"
|
||||
|
||||
baseQuery := `
|
||||
SELECT
|
||||
s.id,
|
||||
s.task_id,
|
||||
t.contest_id,
|
||||
s.participant_id,
|
||||
s.state,
|
||||
s.score,
|
||||
s.penalty,
|
||||
s.total_score,
|
||||
s.language,
|
||||
s.updated_at,
|
||||
s.created_at
|
||||
FROM solutions s
|
||||
LEFT JOIN tasks t ON s.task_id = t.id
|
||||
WHERE 1=1
|
||||
`
|
||||
|
||||
var conditions []string
|
||||
var args []interface{}
|
||||
|
||||
if filters.ContestId != nil {
|
||||
conditions = append(conditions, "contest_id = ?")
|
||||
args = append(args, *filters.ContestId)
|
||||
}
|
||||
if filters.ParticipantId != nil {
|
||||
conditions = append(conditions, "participant_id = ?")
|
||||
args = append(args, *filters.ParticipantId)
|
||||
}
|
||||
if filters.TaskId != nil {
|
||||
conditions = append(conditions, "task_id = ?")
|
||||
args = append(args, *filters.TaskId)
|
||||
}
|
||||
if filters.Language != nil {
|
||||
conditions = append(conditions, "language = ?")
|
||||
args = append(args, *filters.Language)
|
||||
}
|
||||
if filters.State != nil {
|
||||
conditions = append(conditions, "state = ?")
|
||||
args = append(args, *filters.State)
|
||||
}
|
||||
|
||||
if len(conditions) > 0 {
|
||||
baseQuery += " AND " + strings.Join(conditions, " AND ")
|
||||
}
|
||||
|
||||
if filters.Order != nil {
|
||||
orderDirection := "ASC"
|
||||
if *filters.Order < 0 {
|
||||
orderDirection = "DESC"
|
||||
}
|
||||
baseQuery += fmt.Sprintf(" ORDER BY s.id %s", orderDirection)
|
||||
}
|
||||
|
||||
countQuery := "SELECT COUNT(*) FROM (" + baseQuery + ") as count_table"
|
||||
var totalCount int32
|
||||
err := r.db.QueryRowxContext(ctx, r.db.Rebind(countQuery), args...).Scan(&totalCount)
|
||||
if err != nil {
|
||||
return nil, 0, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
offset := (filters.Page - 1) * filters.PageSize
|
||||
baseQuery += " LIMIT ? OFFSET ?"
|
||||
args = append(args, filters.PageSize, offset)
|
||||
|
||||
rows, err := r.db.QueryxContext(ctx, r.db.Rebind(baseQuery), args...)
|
||||
if err != nil {
|
||||
return nil, 0, handlePgErr(err, op)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var solutions []*models.SolutionsListItem
|
||||
for rows.Next() {
|
||||
var solution models.SolutionsListItem
|
||||
err = rows.StructScan(&solution)
|
||||
if err != nil {
|
||||
return nil, 0, handlePgErr(err, op)
|
||||
}
|
||||
solutions = append(solutions, &solution)
|
||||
}
|
||||
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, 0, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
return solutions, totalCount, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue