214 lines
5.7 KiB
Go
214 lines
5.7 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
type ContestRepository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
func NewContestRepository(db *sqlx.DB) *ContestRepository {
|
|
return &ContestRepository{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
const createContestQuery = "INSERT INTO contests (title) VALUES (?) RETURNING id"
|
|
|
|
func (r *ContestRepository) CreateContest(ctx context.Context, title string) (int32, error) {
|
|
const op = "ContestRepository.CreateContest"
|
|
|
|
query := r.db.Rebind(createContestQuery)
|
|
|
|
rows, err := r.db.QueryxContext(ctx, query, title)
|
|
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
|
|
}
|
|
|
|
const readContestByIdQuery = "SELECT * from contests WHERE id=? LIMIT 1"
|
|
|
|
func (r *ContestRepository) ReadContestById(ctx context.Context, id int32) (*models.Contest, error) {
|
|
const op = "ContestRepository.ReadContestById"
|
|
|
|
var contest models.Contest
|
|
query := r.db.Rebind(readContestByIdQuery)
|
|
err := r.db.GetContext(ctx, &contest, query, id)
|
|
if err != nil {
|
|
return nil, handlePgErr(err, op)
|
|
}
|
|
return &contest, nil
|
|
}
|
|
|
|
const deleteContestQuery = "DELETE FROM contests WHERE id=?"
|
|
|
|
func (r *ContestRepository) DeleteContest(ctx context.Context, id int32) error {
|
|
const op = "ContestRepository.DeleteContest"
|
|
|
|
query := r.db.Rebind(deleteContestQuery)
|
|
_, err := r.db.ExecContext(ctx, query, id)
|
|
if err != nil {
|
|
return handlePgErr(err, op)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
const addTaskQuery = "INSERT INTO tasks (problem_id, contest_id, position) VALUES (?, ?,COALESCE(SELECT MAX(position) FROM task WHERE contest_id = ? ,0) + 1) RETURNING id"
|
|
|
|
func (r *ContestRepository) AddTask(ctx context.Context, contestId int32, problem_id int32) (int32, error) {
|
|
const op = "ContestRepository.AddTask"
|
|
|
|
query := r.db.Rebind(addTaskQuery)
|
|
rows, err := r.db.QueryxContext(ctx, query, problem_id, contestId, contestId)
|
|
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
|
|
}
|
|
|
|
const deleteTaskQuery = "DELETE FROM tasks WHERE id=?"
|
|
|
|
func (r *ContestRepository) DeleteTask(ctx context.Context, taskId int32) error {
|
|
const op = "ContestRepository.DeleteTask"
|
|
|
|
query := r.db.Rebind(deleteTaskQuery)
|
|
_, err := r.db.ExecContext(ctx, query, taskId)
|
|
if err != nil {
|
|
return handlePgErr(err, op)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const addParticipantQuery = "INSERT INTO participants (user_id ,contest_id, name) VALUES (?, ?, ?) RETURNING id"
|
|
|
|
func (r *ContestRepository) AddParticipant(ctx context.Context, contestId int32, userId int32) (int32, error) {
|
|
const op = "ContestRepository.AddParticipant"
|
|
|
|
query := r.db.Rebind(addParticipantQuery)
|
|
name := ""
|
|
rows, err := r.db.QueryxContext(ctx, query, contestId, userId, name)
|
|
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, err
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
const deleteParticipantQuery = "DELETE FROM participants WHERE id=?"
|
|
|
|
func (r *ContestRepository) DeleteParticipant(ctx context.Context, participantId int32) error {
|
|
const op = "ContestRepository.DeleteParticipant"
|
|
|
|
query := r.db.Rebind(deleteParticipantQuery)
|
|
_, err := r.db.ExecContext(ctx, query, participantId)
|
|
if err != nil {
|
|
return handlePgErr(err, op)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const readTasksQuery = `SELECT tasks.id,
|
|
problem_id,
|
|
contest_id,
|
|
position,
|
|
title,
|
|
memory_limit,
|
|
time_limit,
|
|
tasks.created_at,
|
|
tasks.updated_at
|
|
FROM tasks
|
|
INNER JOIN problems ON tasks.problem_id = problems.id
|
|
WHERE contest_id = ? ORDER BY position`
|
|
|
|
func (r *ContestRepository) ReadRichTasks(ctx context.Context, contestId int32) ([]*models.RichTask, error) {
|
|
const op = "ContestRepository.ReadTasks"
|
|
|
|
var tasks []*models.RichTask
|
|
query := r.db.Rebind(readTasksQuery)
|
|
err := r.db.SelectContext(ctx, &tasks, query, contestId)
|
|
if err != nil {
|
|
return nil, handlePgErr(err, op)
|
|
}
|
|
return tasks, nil
|
|
}
|
|
|
|
const (
|
|
readContestsListQuery = `SELECT id, title, created_at, updated_at FROM contests LIMIT ? OFFSET ?`
|
|
countContestsQuery = "SELECT COUNT(*) FROM contests"
|
|
)
|
|
|
|
func (r *ContestRepository) ListContests(ctx context.Context, page int32, pageSize int32) ([]*models.ContestsListItem, int32, error) {
|
|
const op = "ContestRepository.ReadTasks"
|
|
|
|
var tasks []*models.ContestsListItem
|
|
query := r.db.Rebind(readContestsListQuery)
|
|
err := r.db.SelectContext(ctx, &tasks, query, pageSize, (page-1)*pageSize)
|
|
if err != nil {
|
|
return nil, 0, handlePgErr(err, op)
|
|
}
|
|
|
|
query = r.db.Rebind(countContestsQuery)
|
|
var count int32
|
|
err = r.db.GetContext(ctx, &count, query)
|
|
if err != nil {
|
|
return nil, 0, handlePgErr(err, op)
|
|
}
|
|
|
|
return tasks, count, nil
|
|
}
|
|
|
|
const (
|
|
readParticipantsListQuery = `SELECT id, user_id, name, created_at, updated_at FROM participants WHERE contest_id = ? LIMIT ? OFFSET ?`
|
|
countParticipantsQuery = "SELECT COUNT(*) FROM participants WHERE contest_id = ?"
|
|
)
|
|
|
|
func (r *ContestRepository) ListParticipants(ctx context.Context, contestId int32, page int32, pageSize int32) ([]*models.ParticipantsListItem, int32, error) {
|
|
const op = "ContestRepository.ReadParticipants"
|
|
|
|
if pageSize > 20 {
|
|
pageSize = 1
|
|
}
|
|
|
|
var participants []*models.ParticipantsListItem
|
|
query := r.db.Rebind(readParticipantsListQuery)
|
|
err := r.db.SelectContext(ctx, &participants, query, contestId, pageSize, (page-1)*pageSize)
|
|
if err != nil {
|
|
return nil, 0, handlePgErr(err, op)
|
|
}
|
|
|
|
query = r.db.Rebind(countParticipantsQuery)
|
|
var count int32
|
|
err = r.db.GetContext(ctx, &count, query, contestId)
|
|
if err != nil {
|
|
return nil, 0, handlePgErr(err, op)
|
|
}
|
|
|
|
return participants, count, nil
|
|
}
|