2024-08-17 12:23:35 +00:00
package storage
import (
"context"
"errors"
"git.sch9.ru/new_gate/ms-auth/internal/lib"
"git.sch9.ru/new_gate/ms-auth/internal/models"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type SolutionStorage struct {
db * sqlx . DB
logger * zap . Logger
}
func NewSolutionStorage ( db * sqlx . DB , logger * zap . Logger ) * SolutionStorage {
return & SolutionStorage {
db : db ,
logger : logger ,
}
}
2024-08-18 12:29:52 +00:00
// TODO: testing graph
2024-08-18 08:18:00 +00:00
func updateResult ( ctx context . Context , participantId int32 , taskId int32 ) error {
tx , err := storage . db . Begin ( )
if err != nil {
return storage . HandlePgErr ( err )
}
2024-08-18 12:29:52 +00:00
query := tx . Rebind ( "UPDATE participant_subtask AS ps SET best_score = (SELECT COALESCE(max(score),0) FROM subtaskruns WHERE subtask_id = ps.subtask_id AND solution_id IN (SELECT id FROM solutions WHERE participant_id=ps.participant_id)) WHERE participant_id = 2 AND subtask_id IN (SELECT id FROM subtasks WHERE task_id = 2)" )
tx . QueryxContext ( ctx , query , participantId , taskId )
query = tx . Rebind ( "UPDATE participant_task SET best_score = (select max(best_score) from participant_subtask WHERE participant_id = ? AND subtask_id IN (SELECT id FROM subtask WHERE task_id = ?)) WHERE participant_id = ? AND task_id = ?" )
tx . QueryxContext ( ctx , query , participantId , taskId , participantId , taskId )
2024-08-18 08:18:00 +00:00
err = tx . Commit ( )
if err != nil {
return storage . HandlePgErr ( err )
}
}
2024-08-17 13:00:34 +00:00
2024-08-17 12:23:35 +00:00
func ( storage * SolutionStorage ) CreateSolution ( ctx context . Context , solution * models . Solution ) ( int32 , error ) {
query := storage . db . Rebind ( `
INSERT INTO solutions
( participant_id , task_id , language_id , solution_hash , result )
VALUES ( ? , ? , ? , ? , ? )
RETURNING id
` )
rows , err := storage . db . QueryxContext (
ctx ,
query ,
solution . ParticipantId ,
solution . TaskId ,
solution . LanguageId ,
"" , //FIXME
models . NotTested ,
)
2024-08-18 14:54:08 +00:00
//TODO: add testing tree
2024-08-17 12:23:35 +00:00
if err != nil {
return 0 , storage . HandlePgErr ( err )
}
defer rows . Close ( )
var id int32
err = rows . StructScan ( & id )
if err != nil {
return 0 , storage . HandlePgErr ( err )
}
return id , nil
}
func ( storage * SolutionStorage ) ReadSolutionById ( ctx context . Context , id int32 ) ( * models . Solution , error ) {
var solution models . Solution
query := storage . db . Rebind ( "SELECT * from solutions WHERE id=? LIMIT 1" )
err := storage . db . GetContext ( ctx , & solution , query , id )
if err != nil {
return nil , storage . HandlePgErr ( err )
}
return & solution , nil
}
2024-08-17 13:00:34 +00:00
func ( storage * SolutionStorage ) RejudgeSolution ( ctx context . Context , id int32 ) error {
2024-08-17 13:41:37 +00:00
tx , err := storage . db . Begin ( )
2024-08-17 13:00:34 +00:00
if err != nil {
return storage . HandlePgErr ( err )
}
2024-08-18 12:29:52 +00:00
query := tx . Rebind ( "UPDATE solutions SET result = ? WHERE id = ?" )
tx . QueryxContext ( ctx , query , models . NotTested , id )
query = tx . Rebind ( "UPDATE subtaskruns SET result = ?,score = 0 WHERE solution_id = ?" )
tx . QueryxContext ( ctx , query , models . NotTested , id )
query = tx . Rebind ( "UPDATE testruns SET result = ?, score = 0 WHERE testgrouprun_id IN (SELECT id FROM tesgrouprun WHERE solution_id = ?)" )
tx . QueryxContext ( ctx , query , models . NotTested , id )
2024-08-17 13:41:37 +00:00
err = tx . Commit ( )
2024-08-18 12:29:52 +00:00
var solution models . Solution
query := storage . db . Rebind ( "SELECT * from solutions WHERE id=? LIMIT 1" )
err := storage . db . GetContext ( ctx , & solution , query , id )
2024-08-17 13:41:37 +00:00
if err != nil {
return storage . HandlePgErr ( err )
}
2024-08-18 12:29:52 +00:00
updateResult ( ctx , solution . ParticipantId , TaskId ) ;
2024-08-17 13:00:34 +00:00
return nil
}
2024-08-17 12:23:35 +00:00
func ( storage * SolutionStorage ) DeleteSolution ( ctx context . Context , id int32 ) error {
2024-08-17 12:40:33 +00:00
query := storage . db . Rebind ( "DELETE FROM solutions WHERE id=?" )
2024-08-17 12:23:35 +00:00
_ , err := storage . db . ExecContext ( ctx , query , id )
if err != nil {
return storage . HandlePgErr ( err )
}
return nil
}