From 318599cfea614cb16000212fbd461c9734a06671 Mon Sep 17 00:00:00 2001 From: Vyacheslav1557 Date: Sat, 29 Mar 2025 03:28:30 +0500 Subject: [PATCH] fix: fix&refactor --- internal/models/pagination.go | 7 ++ .../repository/pg_contests_repository.go | 88 +++++++++++-------- .../repository/pg_problems_repository.go | 21 +++-- internal/tester/usecase/contests_usecase.go | 16 ++-- internal/tester/usecase/problems_usecase.go | 4 +- 5 files changed, 84 insertions(+), 52 deletions(-) diff --git a/internal/models/pagination.go b/internal/models/pagination.go index c2fd852..f158496 100644 --- a/internal/models/pagination.go +++ b/internal/models/pagination.go @@ -4,3 +4,10 @@ type Pagination struct { Page int32 `json:"page"` Total int32 `json:"total"` } + +func Total(count int32, pageSize int32) int32 { + if count%pageSize == 0 { + return count / pageSize + } + return count/pageSize + 1 +} diff --git a/internal/tester/repository/pg_contests_repository.go b/internal/tester/repository/pg_contests_repository.go index ba3b0f8..f989d08 100644 --- a/internal/tester/repository/pg_contests_repository.go +++ b/internal/tester/repository/pg_contests_repository.go @@ -152,7 +152,7 @@ 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.TasksListItem, error) { +func (r *ContestRepository) ReadTasks(ctx context.Context, contestId int32) ([]*models.TasksListItem, error) { const op = "ContestRepository.ReadTasks" var tasks []*models.TasksListItem @@ -169,24 +169,30 @@ const ( countContestsQuery = "SELECT COUNT(*) FROM contests" ) -func (r *ContestRepository) ListContests(ctx context.Context, page int32, pageSize int32) ([]*models.ContestsListItem, int32, error) { +func (r *ContestRepository) ListContests(ctx context.Context, filter models.ContestsFilter) (*models.ContestsList, error) { const op = "ContestRepository.ReadTasks" - var tasks []*models.ContestsListItem + var contests []*models.ContestsListItem query := r.db.Rebind(readContestsListQuery) - err := r.db.SelectContext(ctx, &tasks, query, pageSize, (page-1)*pageSize) + err := r.db.SelectContext(ctx, &contests, query, filter.PageSize, filter.Offset()) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, 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 nil, handlePgErr(err, op) } - return tasks, count, nil + return &models.ContestsList{ + Contests: contests, + Pagination: models.Pagination{ + Total: models.Total(count, filter.PageSize), + Page: filter.Page, + }, + }, nil } const ( @@ -194,28 +200,34 @@ const ( 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) { +func (r *ContestRepository) ListParticipants(ctx context.Context, filter models.ParticipantsFilter) (*models.ParticipantsList, error) { const op = "ContestRepository.ReadParticipants" - if pageSize > 20 { - pageSize = 1 + if filter.PageSize > 20 { + filter.PageSize = 1 } var participants []*models.ParticipantsListItem query := r.db.Rebind(readParticipantsListQuery) - err := r.db.SelectContext(ctx, &participants, query, contestId, pageSize, (page-1)*pageSize) + err := r.db.SelectContext(ctx, &participants, query, filter.ContestId, filter.PageSize, filter.Offset()) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } query = r.db.Rebind(countParticipantsQuery) var count int32 - err = r.db.GetContext(ctx, &count, query, contestId) + err = r.db.GetContext(ctx, &count, query, filter.ContestId) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } - return participants, count, nil + return &models.ParticipantsList{ + Participants: participants, + Pagination: models.Pagination{ + Total: models.Total(count, filter.PageSize), + Page: filter.Page, + }, + }, nil } const ( @@ -301,7 +313,7 @@ func (r *ContestRepository) CreateSolution(ctx context.Context, creation *models return id, nil } -func (r *ContestRepository) ListSolutions(ctx context.Context, filters models.SolutionsFilter) ([]*models.SolutionsListItem, int32, error) { +func (r *ContestRepository) ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error) { const op = "ContestRepository.ListSolutions" baseQuery := ` @@ -325,34 +337,34 @@ func (r *ContestRepository) ListSolutions(ctx context.Context, filters models.So var conditions []string var args []interface{} - if filters.ContestId != nil { + if filter.ContestId != nil { conditions = append(conditions, "contest_id = ?") - args = append(args, *filters.ContestId) + args = append(args, *filter.ContestId) } - if filters.ParticipantId != nil { + if filter.ParticipantId != nil { conditions = append(conditions, "participant_id = ?") - args = append(args, *filters.ParticipantId) + args = append(args, *filter.ParticipantId) } - if filters.TaskId != nil { + if filter.TaskId != nil { conditions = append(conditions, "task_id = ?") - args = append(args, *filters.TaskId) + args = append(args, *filter.TaskId) } - if filters.Language != nil { + if filter.Language != nil { conditions = append(conditions, "language = ?") - args = append(args, *filters.Language) + args = append(args, *filter.Language) } - if filters.State != nil { + if filter.State != nil { conditions = append(conditions, "state = ?") - args = append(args, *filters.State) + args = append(args, *filter.State) } if len(conditions) > 0 { baseQuery += " AND " + strings.Join(conditions, " AND ") } - if filters.Order != nil { + if filter.Order != nil { orderDirection := "ASC" - if *filters.Order < 0 { + if *filter.Order < 0 { orderDirection = "DESC" } baseQuery += fmt.Sprintf(" ORDER BY s.id %s", orderDirection) @@ -362,16 +374,16 @@ func (r *ContestRepository) ListSolutions(ctx context.Context, filters models.So var totalCount int32 err := r.db.QueryRowxContext(ctx, r.db.Rebind(countQuery), args...).Scan(&totalCount) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } - offset := (filters.Page - 1) * filters.PageSize + offset := (filter.Page - 1) * filter.PageSize baseQuery += " LIMIT ? OFFSET ?" - args = append(args, filters.PageSize, offset) + args = append(args, filter.PageSize, offset) rows, err := r.db.QueryxContext(ctx, r.db.Rebind(baseQuery), args...) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } defer rows.Close() @@ -380,16 +392,22 @@ func (r *ContestRepository) ListSolutions(ctx context.Context, filters models.So var solution models.SolutionsListItem err = rows.StructScan(&solution) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } solutions = append(solutions, &solution) } if err = rows.Err(); err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } - return solutions, totalCount, nil + return &models.SolutionsList{ + Solutions: solutions, + Pagination: models.Pagination{ + Total: models.Total(totalCount, filter.PageSize), + Page: filter.Page, + }, + }, nil } const ( diff --git a/internal/tester/repository/pg_problems_repository.go b/internal/tester/repository/pg_problems_repository.go index ecdfe1b..a5dc3c1 100644 --- a/internal/tester/repository/pg_problems_repository.go +++ b/internal/tester/repository/pg_problems_repository.go @@ -63,6 +63,7 @@ func (r *ProblemRepository) ReadProblemById(ctx context.Context, q tester.Querie if err != nil { return nil, handlePgErr(err, op) } + return &problem, nil } @@ -87,18 +88,18 @@ LIMIT ? OFFSET ?` CountProblemsQuery = "SELECT COUNT(*) FROM problems" ) -func (r *ProblemRepository) ListProblems(ctx context.Context, q tester.Querier, page int32, pageSize int32) ([]*models.ProblemsListItem, int32, error) { +func (r *ProblemRepository) ListProblems(ctx context.Context, q tester.Querier, filter models.ProblemsFilter) (*models.ProblemsList, error) { const op = "ContestRepository.ListProblems" - if pageSize > 20 || pageSize < 1 { - pageSize = 1 + if filter.PageSize > 20 || filter.PageSize < 1 { + filter.PageSize = 1 } var problems []*models.ProblemsListItem query := q.Rebind(ListProblemsQuery) - err := q.SelectContext(ctx, &problems, query, pageSize, (page-1)*pageSize) + err := q.SelectContext(ctx, &problems, query, filter.PageSize, filter.Offset()) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } query = q.Rebind(CountProblemsQuery) @@ -106,10 +107,16 @@ func (r *ProblemRepository) ListProblems(ctx context.Context, q tester.Querier, var count int32 err = q.GetContext(ctx, &count, query) if err != nil { - return nil, 0, handlePgErr(err, op) + return nil, handlePgErr(err, op) } - return problems, count, nil + return &models.ProblemsList{ + Problems: problems, + Pagination: models.Pagination{ + Total: models.Total(count, filter.PageSize), + Page: filter.Page, + }, + }, nil } const ( diff --git a/internal/tester/usecase/contests_usecase.go b/internal/tester/usecase/contests_usecase.go index af9bcd9..414c9a2 100644 --- a/internal/tester/usecase/contests_usecase.go +++ b/internal/tester/usecase/contests_usecase.go @@ -46,16 +46,16 @@ func (uc *ContestUseCase) DeleteParticipant(ctx context.Context, participantId i return uc.contestRepo.DeleteParticipant(ctx, participantId) } -func (uc *ContestUseCase) ReadRichTasks(ctx context.Context, contestId int32) ([]*models.TasksListItem, error) { - return uc.contestRepo.ReadRichTasks(ctx, contestId) +func (uc *ContestUseCase) ReadTasks(ctx context.Context, contestId int32) ([]*models.TasksListItem, error) { + return uc.contestRepo.ReadTasks(ctx, contestId) } -func (uc *ContestUseCase) ListContests(ctx context.Context, page int32, pageSize int32) ([]*models.ContestsListItem, int32, error) { - return uc.contestRepo.ListContests(ctx, page, pageSize) +func (uc *ContestUseCase) ListContests(ctx context.Context, filter models.ContestsFilter) (*models.ContestsList, error) { + return uc.contestRepo.ListContests(ctx, filter) } -func (uc *ContestUseCase) ListParticipants(ctx context.Context, contestId int32, page int32, pageSize int32) ([]*models.ParticipantsListItem, int32, error) { - return uc.contestRepo.ListParticipants(ctx, contestId, page, pageSize) +func (uc *ContestUseCase) ListParticipants(ctx context.Context, filter models.ParticipantsFilter) (*models.ParticipantsList, error) { + return uc.contestRepo.ListParticipants(ctx, filter) } func (uc *ContestUseCase) UpdateContest(ctx context.Context, id int32, contestUpdate models.ContestUpdate) error { @@ -74,8 +74,8 @@ func (uc *ContestUseCase) CreateSolution(ctx context.Context, creation *models.S return uc.contestRepo.CreateSolution(ctx, creation) } -func (uc *ContestUseCase) ListSolutions(ctx context.Context, filters models.SolutionsFilter) ([]*models.SolutionsListItem, int32, error) { - return uc.contestRepo.ListSolutions(ctx, filters) +func (uc *ContestUseCase) ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error) { + return uc.contestRepo.ListSolutions(ctx, filter) } func (uc *ContestUseCase) ReadTask(ctx context.Context, id int32) (*models.Task, error) { diff --git a/internal/tester/usecase/problems_usecase.go b/internal/tester/usecase/problems_usecase.go index 785c4a9..2311318 100644 --- a/internal/tester/usecase/problems_usecase.go +++ b/internal/tester/usecase/problems_usecase.go @@ -38,8 +38,8 @@ func (u *ProblemUseCase) DeleteProblem(ctx context.Context, id int32) error { return u.problemRepo.DeleteProblem(ctx, u.problemRepo.DB(), id) } -func (u *ProblemUseCase) ListProblems(ctx context.Context, page int32, pageSize int32) ([]*models.ProblemsListItem, int32, error) { - return u.problemRepo.ListProblems(ctx, u.problemRepo.DB(), page, pageSize) +func (u *ProblemUseCase) ListProblems(ctx context.Context, filter models.ProblemsFilter) (*models.ProblemsList, error) { + return u.problemRepo.ListProblems(ctx, u.problemRepo.DB(), filter) } func (u *ProblemUseCase) UpdateProblem(ctx context.Context, id int32, problemUpdate models.ProblemUpdate) error {