Merge pull request 'feat(solution): update solution fields' (#1) from feature/GAT-93-solution-fileds-update into develop

Reviewed-on: #1
Reviewed-by: OXYgen <oxygen@noreply.localhost>
Reviewed-by: dragonmuffin <dragonmuffin@noreply.localhost>
Reviewed-by: Holoti <holoti@noreply.localhost>
This commit is contained in:
Vyacheslav Birin 2025-04-02 16:00:47 +00:00
commit 18640ada3c
5 changed files with 163 additions and 82 deletions

View file

@ -3,17 +3,29 @@ package models
import "time" import "time"
type Solution struct { type Solution struct {
Id int32 `db:"id"` Id int32 `db:"id"`
TaskId int32 `db:"task_id"`
ParticipantId int32 `db:"participant_id"` ParticipantId int32 `db:"participant_id"`
Solution string `db:"solution"` ParticipantName string `db:"participant_name"`
State int32 `db:"state"`
Score int32 `db:"score"` Solution string `db:"solution"`
Penalty int32 `db:"penalty"`
TotalScore int32 `db:"total_score"` State int32 `db:"state"`
Language int32 `db:"language"` Score int32 `db:"score"`
UpdatedAt time.Time `db:"updated_at"` Penalty int32 `db:"penalty"`
CreatedAt time.Time `db:"created_at"` TimeStat int32 `db:"time_stat"`
MemoryStat int32 `db:"memory_stat"`
Language int32 `db:"language"`
TaskId int32 `db:"task_id"`
TaskPosition int32 `db:"task_position"`
TaskTitle string `db:"task_title"`
ContestId int32 `db:"contest_id"`
ContestTitle string `db:"contest_title"`
UpdatedAt time.Time `db:"updated_at"`
CreatedAt time.Time `db:"created_at"`
} }
type SolutionCreation struct { type SolutionCreation struct {
@ -25,17 +37,27 @@ type SolutionCreation struct {
} }
type SolutionsListItem struct { type SolutionsListItem struct {
Id int32 `db:"id"` Id int32 `db:"id"`
TaskId int32 `db:"task_id"`
ContestId int32 `db:"contest_id"` ParticipantId int32 `db:"participant_id"`
ParticipantId int32 `db:"participant_id"` ParticipantName string `db:"participant_name"`
State int32 `db:"state"`
Score int32 `db:"score"` State int32 `db:"state"`
Penalty int32 `db:"penalty"` Score int32 `db:"score"`
TotalScore int32 `db:"total_score"` Penalty int32 `db:"penalty"`
Language int32 `db:"language"` TimeStat int32 `db:"time_stat"`
UpdatedAt time.Time `db:"updated_at"` MemoryStat int32 `db:"memory_stat"`
CreatedAt time.Time `db:"created_at"` Language int32 `db:"language"`
TaskId int32 `db:"task_id"`
TaskPosition int32 `db:"task_position"`
TaskTitle string `db:"task_title"`
ContestId int32 `db:"contest_id"`
ContestTitle string `db:"contest_title"`
UpdatedAt time.Time `db:"updated_at"`
CreatedAt time.Time `db:"created_at"`
} }
type SolutionsList struct { type SolutionsList struct {

View file

@ -538,32 +538,54 @@ func PTLI2PTLI(p models.ParticipantsListItem) testerv1.ParticipantsListItem {
func SLI2SLI(s models.SolutionsListItem) testerv1.SolutionsListItem { func SLI2SLI(s models.SolutionsListItem) testerv1.SolutionsListItem {
return testerv1.SolutionsListItem{ return testerv1.SolutionsListItem{
ContestId: s.ContestId, Id: s.Id,
CreatedAt: s.CreatedAt,
Id: s.Id, ParticipantId: s.ParticipantId,
Language: s.Language, ParticipantName: s.ParticipantName,
ParticipantId: s.ParticipantId,
Penalty: s.Penalty, State: s.State,
Score: s.Score, Score: s.Score,
State: s.State, Penalty: s.Penalty,
TaskId: s.TaskId, TimeStat: s.TimeStat,
TotalScore: s.TotalScore, MemoryStat: s.MemoryStat,
UpdatedAt: s.UpdatedAt, Language: s.Language,
TaskId: s.TaskId,
TaskPosition: s.TaskPosition,
TaskTitle: s.TaskTitle,
ContestId: s.ContestId,
ContestTitle: s.ContestTitle,
CreatedAt: s.CreatedAt,
UpdatedAt: s.UpdatedAt,
} }
} }
func S2S(s models.Solution) testerv1.Solution { func S2S(s models.Solution) testerv1.Solution {
return testerv1.Solution{ return testerv1.Solution{
Id: s.Id, Id: s.Id,
TaskId: s.TaskId,
ParticipantId: s.ParticipantId, ParticipantId: s.ParticipantId,
Solution: s.Solution, ParticipantName: s.ParticipantName,
State: s.State,
Score: s.Score, Solution: s.Solution,
Penalty: s.Penalty,
TotalScore: s.TotalScore, State: s.State,
Language: s.Language, Score: s.Score,
CreatedAt: s.CreatedAt, Penalty: s.Penalty,
UpdatedAt: s.UpdatedAt, TimeStat: s.TimeStat,
MemoryStat: s.MemoryStat,
Language: s.Language,
TaskId: s.TaskId,
TaskPosition: s.TaskPosition,
TaskTitle: s.TaskTitle,
ContestId: s.ContestId,
ContestTitle: s.ContestTitle,
CreatedAt: s.CreatedAt,
UpdatedAt: s.UpdatedAt,
} }
} }

View file

@ -317,44 +317,56 @@ func (r *ContestRepository) ListSolutions(ctx context.Context, filter models.Sol
const op = "ContestRepository.ListSolutions" const op = "ContestRepository.ListSolutions"
baseQuery := ` baseQuery := `
SELECT SELECT s.id,
s.id,
s.task_id, s.participant_id,
t.contest_id, p2.name as participant_name,
s.participant_id,
s.state, s.state,
s.score, s.score,
s.penalty, s.penalty,
s.total_score, s.time_stat,
s.language, s.memory_stat,
s.updated_at, s.language,
s.created_at
FROM solutions s s.task_id,
LEFT JOIN tasks t ON s.task_id = t.id t.position as task_position,
WHERE 1=1 p.title as task_title,
t.contest_id,
c.title,
s.updated_at,
s.created_at
FROM solutions s
LEFT JOIN tasks t ON s.task_id = t.id
LEFT JOIN problems p ON t.problem_id = p.id
LEFT JOIN contests c ON t.contest_id = c.id
LEFT JOIN participants p2 on s.participant_id = p2.id
WHERE 1=1
` `
var conditions []string var conditions []string
var args []interface{} var args []interface{}
if filter.ContestId != nil { if filter.ContestId != nil {
conditions = append(conditions, "contest_id = ?") conditions = append(conditions, "s.contest_id = ?")
args = append(args, *filter.ContestId) args = append(args, *filter.ContestId)
} }
if filter.ParticipantId != nil { if filter.ParticipantId != nil {
conditions = append(conditions, "participant_id = ?") conditions = append(conditions, "s.participant_id = ?")
args = append(args, *filter.ParticipantId) args = append(args, *filter.ParticipantId)
} }
if filter.TaskId != nil { if filter.TaskId != nil {
conditions = append(conditions, "task_id = ?") conditions = append(conditions, "s.task_id = ?")
args = append(args, *filter.TaskId) args = append(args, *filter.TaskId)
} }
if filter.Language != nil { if filter.Language != nil {
conditions = append(conditions, "language = ?") conditions = append(conditions, "s.language = ?")
args = append(args, *filter.Language) args = append(args, *filter.Language)
} }
if filter.State != nil { if filter.State != nil {
conditions = append(conditions, "state = ?") conditions = append(conditions, "s.state = ?")
args = append(args, *filter.State) args = append(args, *filter.State)
} }
@ -462,42 +474,66 @@ ORDER BY t.position;
solutionsQuery = ` solutionsQuery = `
WITH RankedSolutions AS ( WITH RankedSolutions AS (
SELECT SELECT
s.id, s.id,
s.task_id,
s.participant_id, s.participant_id,
p2.name as participant_name,
s.state, s.state,
s.score, s.score,
s.penalty, s.penalty,
s.total_score, s.time_stat,
s.memory_stat,
s.language, s.language,
s.created_at,
s.updated_at, s.task_id,
t.position as task_position,
p.title as task_title,
t.contest_id, t.contest_id,
c.title as contest_title,
s.updated_at,
s.created_at,
ROW_NUMBER() OVER ( ROW_NUMBER() OVER (
PARTITION BY s.participant_id, s.task_id PARTITION BY s.participant_id, s.task_id
ORDER BY ORDER BY
CASE WHEN s.state = 5 THEN 0 ELSE 1 END, CASE WHEN s.state = 5 THEN 0 ELSE 1 END,
s.created_at s.created_at
) as rn ) as rn
FROM solutions s FROM solutions s
JOIN tasks t ON s.task_id = t.id LEFT JOIN tasks t ON s.task_id = t.id
LEFT JOIN problems p ON t.problem_id = p.id
LEFT JOIN contests c ON t.contest_id = c.id
LEFT JOIN participants p2 on s.participant_id = p2.id
WHERE t.contest_id = ? WHERE t.contest_id = ?
) )
SELECT SELECT
rs.id, rs.id,
rs.task_id,
rs.contest_id,
rs.participant_id, rs.participant_id,
rs.participant_name,
rs.state, rs.state,
rs.score, rs.score,
rs.penalty, rs.penalty,
rs.total_score, rs.time_stat,
rs.memory_stat,
rs.language, rs.language,
rs.created_at,
rs.updated_at rs.task_id,
rs.task_position,
rs.task_title,
rs.contest_id,
rs.contest_title,
rs.updated_at,
rs.created_at
FROM RankedSolutions rs FROM RankedSolutions rs
WHERE rs.rn = 1 WHERE rs.rn = 1;
` `
participantsQuery = ` participantsQuery = `

View file

@ -107,7 +107,8 @@ CREATE TABLE IF NOT EXISTS solutions
state integer NOT NULL DEFAULT 1, state integer NOT NULL DEFAULT 1,
score integer NOT NULL DEFAULT 0, score integer NOT NULL DEFAULT 0,
penalty integer NOT NULL, penalty integer NOT NULL,
total_score integer NOT NULL DEFAULT 0, time_stat integer NOT NULL DEFAULT 0,
memory_stat integer NOT NULL DEFAULT 0,
language integer NOT NULL, language integer NOT NULL,
updated_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(),
created_at timestamptz NOT NULL DEFAULT now(), created_at timestamptz NOT NULL DEFAULT now(),

2
proto

@ -1 +1 @@
Subproject commit 16781a46412eea455f27372045c216126c39d628 Subproject commit 1fbee7ba29c358c76d1c835ac6999ce9e1b59ee9