From 700cdecfc5a7206a344ca5ea45cc19b4f914d259 Mon Sep 17 00:00:00 2001 From: Vyacheslav1557 Date: Sun, 2 Mar 2025 13:38:29 +0500 Subject: [PATCH] fix(tester): extend ListProblems endpoint --- internal/models/problem.go | 9 ++++++ internal/tester/delivery.go | 2 +- internal/tester/delivery/rest/handlers.go | 31 +++++++++++++++++-- internal/tester/pg_repository.go | 1 + .../repository/pg_problems_repository.go | 30 ++++++++++++++++++ internal/tester/usecase.go | 1 + internal/tester/usecase/problems_usecase.go | 4 +++ 7 files changed, 75 insertions(+), 3 deletions(-) diff --git a/internal/models/problem.go b/internal/models/problem.go index e85fbe7..1f23be1 100644 --- a/internal/models/problem.go +++ b/internal/models/problem.go @@ -16,3 +16,12 @@ type Problem struct { CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` } + +type ProblemListItem struct { + Id int32 `db:"id"` + Title string `db:"title"` + MemoryLimit int32 `db:"memory_limit"` + TimeLimit int32 `db:"time_limit"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` +} diff --git a/internal/tester/delivery.go b/internal/tester/delivery.go index 79fb2b3..58eeea0 100644 --- a/internal/tester/delivery.go +++ b/internal/tester/delivery.go @@ -14,7 +14,7 @@ type Handlers interface { AddParticipant(c *fiber.Ctx, id int32, params testerv1.AddParticipantParams) error DeleteTask(c *fiber.Ctx, id int32, params testerv1.DeleteTaskParams) error AddTask(c *fiber.Ctx, id int32, params testerv1.AddTaskParams) error - ListProblems(c *fiber.Ctx) error + ListProblems(c *fiber.Ctx, params testerv1.ListProblemsParams) error CreateProblem(c *fiber.Ctx) error DeleteProblem(c *fiber.Ctx, id int32) error GetProblem(c *fiber.Ctx, id int32) error diff --git a/internal/tester/delivery/rest/handlers.go b/internal/tester/delivery/rest/handlers.go index f95b233..56cfedc 100644 --- a/internal/tester/delivery/rest/handlers.go +++ b/internal/tester/delivery/rest/handlers.go @@ -23,8 +23,35 @@ func (h *TesterHandlers) ListContests(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusNotImplemented) } -func (h *TesterHandlers) ListProblems(c *fiber.Ctx) error { - return c.SendStatus(fiber.StatusNotImplemented) +func (h *TesterHandlers) ListProblems(c *fiber.Ctx, params testerv1.ListProblemsParams) error { + problems, count, err := h.problemsUC.ListProblems(c.Context(), params.Page, params.PageSize) + if err != nil { + return c.SendStatus(pkg.ToREST(err)) + } + + resp := testerv1.ListProblemsResponse{ + Problems: make([]testerv1.ProblemListItem, len(problems)), + Page: params.Page, + MaxPage: func() int32 { + if count%params.PageSize == 0 { + return count / params.PageSize + } + return count/params.PageSize + 1 + }(), + } + + for i, problem := range problems { + resp.Problems[i] = testerv1.ProblemListItem{ + Id: problem.Id, + Title: problem.Title, + MemoryLimit: problem.MemoryLimit, + TimeLimit: problem.TimeLimit, + CreatedAt: problem.CreatedAt, + UpdatedAt: problem.UpdatedAt, + } + } + + return c.JSON(resp) } func (h *TesterHandlers) CreateContest(c *fiber.Ctx) error { diff --git a/internal/tester/pg_repository.go b/internal/tester/pg_repository.go index 365dca1..0f045a3 100644 --- a/internal/tester/pg_repository.go +++ b/internal/tester/pg_repository.go @@ -9,6 +9,7 @@ type ProblemPostgresRepository interface { CreateProblem(ctx context.Context, title string) (int32, error) ReadProblemById(ctx context.Context, id int32) (*models.Problem, error) DeleteProblem(ctx context.Context, id int32) error + ListProblems(ctx context.Context, page int32, pageSize int32) ([]*models.ProblemListItem, int32, error) } type ContestRepository interface { diff --git a/internal/tester/repository/pg_problems_repository.go b/internal/tester/repository/pg_problems_repository.go index b171092..4108746 100644 --- a/internal/tester/repository/pg_problems_repository.go +++ b/internal/tester/repository/pg_problems_repository.go @@ -67,3 +67,33 @@ func (r *ProblemRepository) DeleteProblem(ctx context.Context, id int32) error { return nil } + +const ( + ListProblemsQuery = `SELECT id, title, time_limit, memory_limit, created_at, updated_at +FROM problems +LIMIT ? OFFSET ?` + CountProblemsQuery = "SELECT COUNT(*) FROM problems" +) + +func (r *ProblemRepository) ListProblems(ctx context.Context, page int32, pageSize int32) ([]*models.ProblemListItem, int32, error) { + const op = "ContestRepository.ListProblems" + + if pageSize > 20 || pageSize < 1 { + pageSize = 1 + } + + var problems []*models.ProblemListItem + query := r.db.Rebind(ListProblemsQuery) + err := r.db.SelectContext(ctx, &problems, query, pageSize, (page-1)*pageSize) + if err != nil { + return nil, 0, handlePgErr(err, op) + } + + var count int32 + err = r.db.GetContext(ctx, &count, CountProblemsQuery) + if err != nil { + return nil, 0, handlePgErr(err, op) + } + + return problems, count, nil +} diff --git a/internal/tester/usecase.go b/internal/tester/usecase.go index 707bce5..5457e6b 100644 --- a/internal/tester/usecase.go +++ b/internal/tester/usecase.go @@ -9,6 +9,7 @@ type ProblemUseCase interface { CreateProblem(ctx context.Context, title string) (int32, error) ReadProblemById(ctx context.Context, id int32) (*models.Problem, error) DeleteProblem(ctx context.Context, id int32) error + ListProblems(ctx context.Context, page int32, pageSize int32) ([]*models.ProblemListItem, int32, error) } type ContestUseCase interface { diff --git a/internal/tester/usecase/problems_usecase.go b/internal/tester/usecase/problems_usecase.go index b3eb827..0c01d68 100644 --- a/internal/tester/usecase/problems_usecase.go +++ b/internal/tester/usecase/problems_usecase.go @@ -32,3 +32,7 @@ func (u *ProblemUseCase) ReadProblemById(ctx context.Context, id int32) (*models func (u *ProblemUseCase) DeleteProblem(ctx context.Context, id int32) error { return u.problemRepo.DeleteProblem(ctx, id) } + +func (u *ProblemUseCase) ListProblems(ctx context.Context, page int32, pageSize int32) ([]*models.ProblemListItem, int32, error) { + return u.problemRepo.ListProblems(ctx, page, pageSize) +}