fix: make it runnable

This commit is contained in:
Vyacheslav1557 2024-08-21 03:54:46 +05:00
parent c9c4fc65e7
commit bf508a5f1f
23 changed files with 311 additions and 286 deletions

8
go.mod
View file

@ -1,9 +1,10 @@
module git.sch9.ru/new_gate/ms-tester
go 1.19
go 1.21.3
toolchain go1.22.0
require (
git.sch9.ru/new_gate/ms-auth v0.0.0-20240816164331-331e413afa6a
github.com/ilyakaznacheev/cleanenv v1.5.0
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438
github.com/open-policy-agent/opa v0.67.1
@ -25,6 +26,7 @@ require (
github.com/gorilla/mux v1.8.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.48.0 // indirect
@ -42,6 +44,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
@ -51,7 +54,6 @@ require (
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/jackc/pgx/v5 v5.6.0
github.com/jmoiron/sqlx v1.4.0
github.com/joho/godotenv v1.5.1 // indirect

6
go.sum
View file

@ -1,7 +1,5 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.sch9.ru/new_gate/ms-auth v0.0.0-20240816164331-331e413afa6a h1:Gvi3+Qh2VW3iWG3TZWQLjkWeW/4gb621SLLr9BroOro=
git.sch9.ru/new_gate/ms-auth v0.0.0-20240816164331-331e413afa6a/go.mod h1:BL4MiDqgmLngmQqUcKQ1cK1XCJr9DlAOpWnrlGidDdE=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
@ -51,8 +49,6 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@ -82,6 +78,8 @@ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=

View file

@ -1,22 +1,9 @@
package lib
import (
"fmt"
"github.com/ilyakaznacheev/cleanenv"
)
type Config struct {
Env string `env:"ENV" env-default:"prod"`
Pandoc string `env:"PANDOC" required:"true"`
Auth string `env:"PANDOC" required:"true"`
Address string `env:"ADDRESS" required:"true"`
PostgresDSN string `env:"POSTGRES_DSN" required:"true"`
JWTSecret string `env:"JWT_SECRET" required:"true"`
}
func MustSetupConfig() *Config {
var cfg Config
err := cleanenv.ReadConfig(".env", &cfg)
if err != nil {
panic(fmt.Sprintf("error reading config: %s", err.Error()))
}
return &cfg
}

View file

@ -16,4 +16,5 @@ var (
var (
ErrBadTestingStrategy = errors.New("bad testing strategy")
ErrBadResult = errors.New("bad result")
)

View file

@ -1,8 +1,10 @@
package models
import "time"
type Contest struct {
Id *int `db:"id"`
Name *string `db:"name"`
CreatedAt *time.Time `db:"created_at"`
UpdatedAt *time.Time `db:"updated_at"`
Id *int `db:"id"`
Name *string `db:"name"`
CreatedAt *time.Time `db:"created_at"`
UpdatedAt *time.Time `db:"updated_at"`
}

View file

@ -1,10 +1,8 @@
package models
import "time"
type Solution struct {
Id *int32 `db:"id"`
UserId *int32 `db:"user_id"`
ContestId *int32 `db:"contest_id"`
Name *string `db:"name"`
type Participant struct {
Id *int32 `db:"id"`
UserId *int32 `db:"user_id"`
ContestId *int32 `db:"contest_id"`
Name *string `db:"name"`
}

View file

@ -1,23 +1,23 @@
package models
import "time"
import "git.sch9.ru/new_gate/ms-tester/internal/lib"
type Result int32
const (
NotTested Result = 0 // change only with schema change
Accepted Result = 1
CompilationError Result = 2
MemoryLimitExceeded Result = 3
TimeLimitExceeded Result = 4
SystemFailDuringTesting Result = 5
Testing Result = 6
NotTested Result = 0 // change only with schema change
Accepted Result = 1
CompilationError Result = 2
MemoryLimitExceeded Result = 3
TimeLimitExceeded Result = 4
SystemFailDuringTesting Result = 5
Testing Result = 6
)
func (result Result) Valid() error {
switch result {
case NotTested, Accepted, TimeLimitExceeded, MemoryLimitExceede, CompilationError, SystemFailDuringTesting:
return nil
}
return lib.ErrBadResult
switch result {
case NotTested, Accepted, TimeLimitExceeded, MemoryLimitExceeded, CompilationError, SystemFailDuringTesting:
return nil
}
return lib.ErrBadResult
}

View file

@ -1,8 +1,8 @@
package models
type Task struct {
Id *int32 `db:"id"`
ContestId *int32 `db:"contest_id"`
TestgroupId *int32 `db:"testgroup_id"`
TaskId *int32 `db:"task_id"`
type SubTask struct {
Id *int32 `db:"id"`
ContestId *int32 `db:"contest_id"`
TestgroupId *int32 `db:"testgroup_id"`
TaskId *int32 `db:"task_id"`
}

View file

@ -1,26 +1,26 @@
package models
import "time"
import "git.sch9.ru/new_gate/ms-tester/internal/lib"
type TestingStrategy int32
const (
EachTestTS TestingStrategy = 1;
CompleteGroupTS TestingStrategy = 2;
EachTestTS TestingStrategy = 1
CompleteGroupTS TestingStrategy = 2
)
type Testgroup struct {
Id *int32 `db:"id"`
ProblemId *int32 `db:"problem_id"`
TestingStrategy *TestingStrategy `db:"testing_strategy"`
Id *int32 `db:"id"`
ProblemId *int32 `db:"problem_id"`
TestingStrategy *TestingStrategy `db:"testing_strategy"`
}
type TestgroupData struct {
Ts TestingStrategy
TestAmount int32
type TestGroupData struct {
Ts TestingStrategy
TestAmount int32
}
func (TestingStrategy ts) Valid() error {
func (ts TestingStrategy) Valid() error {
switch ts {
case EachTestTS, CompleteGroupTS:
return nil

View file

@ -25,26 +25,25 @@ func NewContestService(
}
func (service *ContestService) CreateContest(ctx context.Context, contest *models.Contest) (int32, error) {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.contestStorage.CreateContest(ctx, contest)
}
func (service *ContestService) ReadContestById(ctx context.Context, id int32) (*models.Contest, error) {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.contestStorage.ReadContestById(ctx, id)
}
func (service *ContestService) UpdateContest(ctx context.Context, contest *models.Contest) error {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.contestStorage.UpdateContest(ctx, contest)
}
func (service *ContestService) DeleteContest(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.contestStorage.DeleteContest(ctx, id)
}

View file

@ -25,25 +25,25 @@ func NewLanguageService(
}
func (service *LanguageService) CreateLanguage(ctx context.Context, language *models.Language) (int32, error) {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.languageStorage.CreateLanguage(ctx, language)
}
func (service *LanguageService) ReadLanguageById(ctx context.Context, id int32) (*models.Language, error) {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.languageStorage.ReadLanguageById(ctx, id)
}
func (service *LanguageService) UpdateLanguage(ctx context.Context, language *models.Language) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.languageStorage.UpdateLanguage(ctx, language)
}
func (service *LanguageService) DeleteLanguage(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.languageStorage.DeleteLanguage(ctx, id)
}

View file

@ -25,25 +25,25 @@ func NewParticipantService(
}
func (service *ParticipantService) CreateParticipant(ctx context.Context, participant *models.Participant) (int32, error) {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.participantStorage.CreateParticipant(ctx, participant)
}
func (service *ParticipantService) ReadParticipantById(ctx context.Context, id int32) (*models.Participant, error) {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.participantStorage.ReadParticipantById(ctx, id)
}
func (service *ParticipantService) UpdateParticipant(ctx context.Context, participant *models.Participant) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.participantStorage.UpdateParticipant(ctx, participant)
}
func (service *ParticipantService) DeleteParticipant(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.participantStorage.DeleteParticipant(ctx, id)
}

View file

@ -6,14 +6,14 @@ import (
)
type ProblemStorage interface {
CreateProblem(ctx context.Context, problem *models.Problem) (int32, error)
CreateProblem(ctx context.Context, problem *models.Problem, testGroupData []models.TestGroupData) (int32, error)
ReadProblemById(ctx context.Context, id int32) (*models.Problem, error)
UpdateProblem(ctx context.Context, problem *models.Problem) error
DeleteProblem(ctx context.Context, id int32) error
}
type PandocClient interface {
ConvertLatexToHtml5(text string) (string, error)
ConvertLatexToHtml5(ctx context.Context, text string) (string, error)
}
type ProblemService struct {
@ -32,29 +32,29 @@ func NewProblemService(
}
func (service *ProblemService) CreateProblem(ctx context.Context, problem *models.Problem, ch <-chan []byte) (int32, error) {
userId := ctx.Value("user_id").(int32)
html, err := service.pandocClient.ConvertLatexToHtml5(*problem.Description)
if err != nil {
return 0, err
}
//userId := ctx.Value("user_id").(int32)
//html, err := service.pandocClient.ConvertLatexToHtml5(*problem.Description)
//if err != nil {
// return 0, err
//}
panic("access control is not implemented yet")
return service.problemStorage.CreateProblem(ctx, problem)
//return service.problemStorage.CreateProblem(ctx, problem)
}
func (service *ProblemService) ReadProblemById(ctx context.Context, id int32) (*models.Problem, error) {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.problemStorage.ReadProblemById(ctx, id)
//return service.problemStorage.ReadProblemById(ctx, id)
}
func (service *ProblemService) UpdateProblem(ctx context.Context, problem *models.Problem) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.problemStorage.UpdateProblem(ctx, problem)
//return service.problemStorage.UpdateProblem(ctx, problem)
}
func (service *ProblemService) DeleteProblem(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.problemStorage.DeleteProblem(ctx, id)
//return service.problemStorage.DeleteProblem(ctx, id)
}

View file

@ -1,50 +1,49 @@
package services
import (
"context"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"context"
"git.sch9.ru/new_gate/ms-tester/internal/models"
)
type SolutionStorage interface {
CreateSolution(ctx context.Context, models.Solution) (int32, error)
ReadSolutionById(ctx context.Context, id int32) (models.Solution, error)
RejudgeSolution(ctx context.Context, id int32) error
DeleteSolution(ctx context.Context, id int32) error
CreateSolution(ctx context.Context, solution models.Solution) (int32, error)
ReadSolutionById(ctx context.Context, id int32) (models.Solution, error)
RejudgeSolution(ctx context.Context, id int32) error
DeleteSolution(ctx context.Context, id int32) error
}
type SolutionService struct {
solutionStorage SolutionStorage
solutionStorage SolutionStorage
}
func NewSolutionService(
solutionStorage SolutionStorage,
solutionStorage SolutionStorage,
) *SolutionService {
return &SolutionService{
solutionStorage: solutionStorage,
}
return &SolutionService{
solutionStorage: solutionStorage,
}
}
func (service *SolutionService) CreateSolution(ctx context.Context, solution models.Solution) (int32, error) {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.CreateSolution(ctx, solution)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.CreateSolution(ctx, solution)
}
func (service *SolutionService) ReadSolutionById(ctx context.Context, id int32) (models.Solution, error) {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.ReadSolutionById(ctx, id)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.ReadSolutionById(ctx, id)
}
func (service *SolutionService) RejudgeSolution(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.RejudgeSolution(ctx, id)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.RejudgeSolution(ctx, id)
}
func (service *SolutionService) DeleteSolution(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.DeleteSolution(ctx, id)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.solutionStorage.DeleteSolution(ctx, id)
}

View file

@ -1,36 +1,35 @@
package services
import (
"context"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"context"
"git.sch9.ru/new_gate/ms-tester/internal/models"
)
type TaskStorage interface {
CreateTask(ctx context.Context, models.Task) (int32, error)
DeleteTask(ctx context.Context, id int32) error
CreateTask(ctx context.Context, task models.Task) (int32, error)
DeleteTask(ctx context.Context, id int32) error
}
type TaskService struct {
taskStorage TaskStorage
taskStorage TaskStorage
}
func NewTaskService(
taskStorage TaskStorage,
taskStorage TaskStorage,
) *TaskService {
return &TaskService{
taskStorage: taskStorage,
}
return &TaskService{
taskStorage: taskStorage,
}
}
func (service *TaskService) CreateTask(ctx context.Context, task models.Task) (int32, error) {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.taskStorage.CreateTask(ctx, task)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.taskStorage.CreateTask(ctx, task)
}
func (service *TaskService) DeleteTask(ctx context.Context, id int32) error {
userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.taskStorage.DeleteTask(ctx, id)
//userId := ctx.Value("user_id").(int32)
panic("access control is not implemented yet")
return service.taskStorage.DeleteTask(ctx, id)
}

View file

@ -57,12 +57,14 @@ func (storage *ContestStorage) ReadContestById(ctx context.Context, id int32) (*
return &contest, nil
}
func (storage *ContestStorage) UpdateContest(ctx context.Context, id int32, contest models.Contest) error {
query := storage.db.Rebind("UPDATE contests SET name=?")
_, err := storage.db.ExecContext(ctx, query, contest.Name)
func (storage *ContestStorage) UpdateContest(ctx context.Context, contest *models.Contest) error {
query := storage.db.Rebind("UPDATE contests SET name=? WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, contest.Name, contest.Id)
if err != nil {
return handlePgErr(err)
}
return nil
}
func (storage *ContestStorage) DeleteContest(ctx context.Context, id int32) error {

View file

@ -2,14 +2,9 @@ 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"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type LanguageStorage struct {
@ -36,18 +31,18 @@ RETURNING id
ctx,
query,
language.Name,
"",//FIXME
""
"", //FIXME
"",
)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
defer rows.Close()
var id int32
err = rows.StructScan(&id)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
return id, nil
@ -59,26 +54,27 @@ func (storage *LanguageStorage) ReadLanguageById(ctx context.Context, id int32)
query := storage.db.Rebind("SELECT * from languages WHERE id=? LIMIT 1")
err := storage.db.GetContext(ctx, &language, query, id)
if err != nil {
return nil, storage.HandlePgErr(err)
return nil, handlePgErr(err)
}
return &language, nil
}
func (storage *LanguageStorage) UpdateLanguage(ctx context.Context, id int32,language models.Language) error {
query := storage.db.Rebind("UPDATE languages SET name=?")//FIXME add build file and execute file loading
func (storage *LanguageStorage) UpdateLanguage(ctx context.Context, id int32, language models.Language) error {
query := storage.db.Rebind("UPDATE languages SET name=?") //FIXME add build file and execute file loading
_, err := storage.db.ExecContext(ctx, query, language.Name)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}
func (storage *LanguageStorage) DeleteLanguage(ctx context.Context, id int32) error {
query := storage.db.Rebind("DELETE FROM languages WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}

View file

@ -2,14 +2,9 @@ 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"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type ParticipantStorage struct {
@ -37,17 +32,17 @@ RETURNING id
query,
participant.UserId,
participant.ContestId,
participant.Name
participant.Name,
)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
defer rows.Close()
var id int32
err = rows.StructScan(&id)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
return id, nil
@ -59,26 +54,26 @@ func (storage *ParticipantStorage) ReadParticipantById(ctx context.Context, id i
query := storage.db.Rebind("SELECT * from participants WHERE id=? LIMIT 1")
err := storage.db.GetContext(ctx, &participant, query, id)
if err != nil {
return nil, storage.HandlePgErr(err)
return nil, handlePgErr(err)
}
return &participant, nil
}
func (storage *ParticipantStorage) UpdateParticipant(ctx context.Context, id int32,participant models.Participant) error {
func (storage *ParticipantStorage) UpdateParticipant(ctx context.Context, id int32, participant models.Participant) error {
query := storage.db.Rebind("UPDATE participants SET name=?")
_, err := storage.db.ExecContext(ctx, query, participant.Name)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}
func (storage *ParticipantStorage) DeleteParticipant(ctx context.Context, id int32) error {
query := storage.db.Rebind("DELETE FROM participants WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}

View file

@ -2,14 +2,9 @@ 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"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type ProblemStorage struct {
@ -24,8 +19,8 @@ func NewProblemStorage(db *sqlx.DB, logger *zap.Logger) *ProblemStorage {
}
}
func (storage *ProblemStorage) CreateProblem(ctx context.Context, problem *models.Problem, testgroupData []models.TestGroupData, testchan <-chan []byte) (int32, error) {
tx,err := storage.db.Begin()
func (storage *ProblemStorage) CreateProblem(ctx context.Context, problem *models.Problem, testGroupData []models.TestGroupData) (int32, error) {
tx, err := storage.db.Beginx()
query := tx.Rebind(`
INSERT INTO problems
(name,description,time_limit,memory_limit)
@ -35,46 +30,47 @@ RETURNING id
rows, err := tx.QueryxContext(
ctx,
query,
problem.Name,
problem.Description,
problem.TimeLimit,
problem.MemoryLimit
problem.Name,
problem.Description,
problem.TimeLimit,
problem.MemoryLimit,
)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
for _,tgd := testGroupData {
query := tx.Rebind(`
for _, tgd := range testGroupData {
query := tx.Rebind(`
INSERT INTO testgroups
(problem_id,testing_strategy)
VALUES ((select last_value from problems_id_seq),?)
RETURNING id
`)
rows, err := tx.QueryxContext(ctx, query, tgd.Ts)
if err != nil {
return 0, storage.HandlePgErr(err)
}
for i:=0;i<tgd.testAmount;i++ {
query := tx.Rebind(`
rows, err = tx.QueryxContext(ctx, query, tgd.Ts)
if err != nil {
return 0, handlePgErr(err)
}
var i int32 = 0
for ; i < tgd.TestAmount; i++ {
query := tx.Rebind(`
INSERT INTO tests
(testgroup_id)
VALUES ((select last_value from testgroups_id_seq))
RETURNING id
`)
rows, err := tx.QueryxContext(ctx, query, tgd.Ts)
if err != nil {
return 0, storage.HandlePgErr(err)
}
}
}
err = tx.Commit()
//add test saving
rows, err = tx.QueryxContext(ctx, query, tgd.Ts)
if err != nil {
return 0, handlePgErr(err)
}
}
}
err = tx.Commit()
//add test saving
defer rows.Close()
var id int32
err = rows.StructScan(&id)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
return id, nil
@ -85,26 +81,26 @@ func (storage *ProblemStorage) ReadProblemById(ctx context.Context, id int32) (*
query := storage.db.Rebind("SELECT * from problems WHERE id=? LIMIT 1")
err := storage.db.GetContext(ctx, &problem, query, id)
if err != nil {
return nil, storage.HandlePgErr(err)
return nil, handlePgErr(err)
}
return &problem, nil
}
func (storage *ProblemStorage) UpdateProblem(ctx context.Context, id int32,problem models.Problem) error {
query := storage.db.Rebind("UPDATE problems SET name=?,description=?,time_limit=?,memory_limit=?")
_, err := storage.db.ExecContext(ctx, query, problem.Name,Problem.Description,problem.TimeLimit,problem.MemoryLimit)
func (storage *ProblemStorage) UpdateProblem(ctx context.Context, problem *models.Problem) error {
query := storage.db.Rebind("UPDATE problems SET name=?,description=?,time_limit=?,memory_limit=? WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, problem.Name, problem.Description, problem.TimeLimit, problem.MemoryLimit, problem.Id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}
func (storage *ProblemStorage) DeleteProblem(ctx context.Context, id int32) error {
query := storage.db.Rebind("DELETE FROM problems WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}

View file

@ -2,14 +2,9 @@ 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"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type SolutionStorage struct {
@ -26,19 +21,21 @@ func NewSolutionStorage(db *sqlx.DB, logger *zap.Logger) *SolutionStorage {
// TODO: testing graph
func updateResult(ctx context.Context, participantId int32, taskId int32) error {
tx,err := storage.db.Begin()
func (storage *SolutionStorage) updateResult(ctx context.Context, participantId int32, taskId int32) error {
tx, err := storage.db.Beginx()
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
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)
err = tx.Commit()
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)
err = tx.Commit()
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}
func (storage *SolutionStorage) CreateSolution(ctx context.Context, solution *models.Solution) (int32, error) {
@ -55,19 +52,19 @@ RETURNING id
solution.ParticipantId,
solution.TaskId,
solution.LanguageId,
"",//FIXME
"", //FIXME
models.NotTested,
)
//TODO: add testing tree
//TODO: add testing tree
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
defer rows.Close()
var id int32
err = rows.StructScan(&id)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
return id, nil
@ -78,30 +75,30 @@ func (storage *SolutionStorage) ReadSolutionById(ctx context.Context, id int32)
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 nil, handlePgErr(err)
}
return &solution, nil
}
func (storage *SolutionStorage) RejudgeSolution(ctx context.Context, id int32) error {
tx,err := storage.db.Begin()
tx, err := storage.db.Beginx()
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
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)
err = tx.Commit()
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)
err = tx.Commit()
var solution models.Solution
query := storage.db.Rebind("SELECT * from solutions WHERE id=? LIMIT 1")
err := storage.db.GetContext(ctx, &solution, query, id)
query = storage.db.Rebind("SELECT * from solutions WHERE id=? LIMIT 1")
err = storage.db.GetContext(ctx, &solution, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
updateResult(ctx,solution.ParticipantId,TaskId);
storage.updateResult(ctx, *solution.ParticipantId, *solution.TaskId)
return nil
}
@ -110,9 +107,8 @@ func (storage *SolutionStorage) DeleteSolution(ctx context.Context, id int32) er
query := storage.db.Rebind("DELETE FROM solutions WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}

View file

@ -2,14 +2,9 @@ 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"
"git.sch9.ru/new_gate/ms-tester/internal/models"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"time"
)
type TaskStorage struct {
@ -38,17 +33,17 @@ RETURNING id
task.ContestId,
task.ProblemId,
task.Position,
task.PositionName
task.PositionName,
)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
defer rows.Close()
var id int32
err = rows.StructScan(&id)
if err != nil {
return 0, storage.HandlePgErr(err)
return 0, handlePgErr(err)
}
return id, nil
@ -60,26 +55,26 @@ func (storage *TaskStorage) ReadTaskById(ctx context.Context, id int32) (*models
query := storage.db.Rebind("SELECT * from tasks WHERE id=? LIMIT 1")
err := storage.db.GetContext(ctx, &task, query, id)
if err != nil {
return nil, storage.HandlePgErr(err)
return nil, handlePgErr(err)
}
return &task, nil
}
func (storage *TaskStorage) UpdateTask(ctx context.Context, id int32,task models.Task) error {
func (storage *TaskStorage) UpdateTask(ctx context.Context, id int32, task models.Task) error {
query := storage.db.Rebind("UPDATE tasks SET position=?,position_name=?")
_, err := storage.db.ExecContext(ctx, query, task.Position,task.PositionName)
_, err := storage.db.ExecContext(ctx, query, task.Position, task.PositionName)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}
func (storage *TaskStorage) DeleteTask(ctx context.Context, id int32) error {
query := storage.db.Rebind("DELETE FROM tasks WHERE id=?")
_, err := storage.db.ExecContext(ctx, query, id)
if err != nil {
return storage.HandlePgErr(err)
return handlePgErr(err)
}
return nil
}

View file

@ -7,6 +7,7 @@ import (
sessionv1 "git.sch9.ru/new_gate/ms-tester/pkg/go/gen/proto/session/v1"
"go.uber.org/zap"
"google.golang.org/protobuf/types/known/timestamppb"
"net"
"time"
"google.golang.org/grpc"
@ -51,15 +52,16 @@ type TesterServer struct {
func NewTesterServer(
problemService ProblemService,
sessionClient SessionClient,
permissionService PermissionService,
userService UserService,
logger *zap.Logger,
) *TesterServer {
server := &TesterServer{
problemService: problemService,
sessionClient: sessionClient,
userService: userService,
logger: logger,
problemService: problemService,
sessionClient: sessionClient,
permissionService: permissionService,
userService: userService,
logger: logger,
}
grpcServer := grpc.NewServer(
@ -69,9 +71,19 @@ func NewTesterServer(
problemv1.RegisterProblemServiceServer(grpcServer, server)
server.grpcServer = grpcServer
return server
}
func (s *TesterServer) Start(lis net.Listener) error {
return s.grpcServer.Serve(lis)
}
func (s *TesterServer) Stop() {
s.grpcServer.GracefulStop()
}
func AsTimeP(t *timestamppb.Timestamp) *time.Time {
if t == nil {
return nil

106
main.go
View file

@ -1,33 +1,81 @@
package main
func main() {
//cfg := lib.MustSetupConfig()
//
//var logger *zap.Logger
//if cfg.Env == "prod" {
// logger = zap.Must(zap.NewProduction())
//} else if cfg.Env == "dev" {
// logger = zap.Must(zap.NewDevelopment())
//} else {
// panic(fmt.Sprintf(`error reading config: env expected "prod" or "dev", got "%s"`, cfg.Env))
//}
import (
"fmt"
"git.sch9.ru/new_gate/ms-tester/internal/lib"
"git.sch9.ru/new_gate/ms-tester/internal/services"
"git.sch9.ru/new_gate/ms-tester/internal/storage"
"git.sch9.ru/new_gate/ms-tester/internal/transport"
sessionv1 "git.sch9.ru/new_gate/ms-tester/pkg/go/gen/proto/session/v1"
"github.com/ilyakaznacheev/cleanenv"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"net"
"net/http"
"os"
"os/signal"
"syscall"
)
//postgres := storage.NewUserStorage(cfg.PostgresDSN, logger)
//
//vk := storage.NewValkeyStorage(cfg.RedisDSN, cfg, logger)
//
//sessionService := services.NewSessionService(vk, postgres, cfg)
//userService := services.NewUserService(postgres, vk, vk, cfg)
//
//server := transport.NewAuthServer(sessionService, userService, grpc.NewServer(), logger)
//
//application := app.NewApp(cfg, server)
//
//application.Start()
//
//stop := make(chan os.Signal, 1)
//signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)
//
//<-stop
//application.GracefullyStop()
func main() {
var cfg lib.Config
err := cleanenv.ReadConfig(".env", &cfg)
if err != nil {
panic(fmt.Sprintf("error reading config: %s", err.Error()))
}
var logger *zap.Logger
if cfg.Env == "prod" {
logger = zap.Must(zap.NewProduction())
} else if cfg.Env == "dev" {
logger = zap.Must(zap.NewDevelopment())
} else {
panic(fmt.Sprintf(`error reading config: env expected "prod" or "dev", got "%s"`, cfg.Env))
}
db, err := sqlx.Connect("pgx", cfg.PostgresDSN)
if err != nil {
panic(err)
}
defer db.Close()
//contestStorage := storage.NewContestStorage(db, logger)
//contestService := services.NewContestService(contestStorage)
pandocClient := lib.NewPandocClient(&http.Client{}, cfg.Pandoc)
grpcSessionClient, err := grpc.NewClient(cfg.Auth, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
sessionClient := sessionv1.NewSessionServiceClient(grpcSessionClient)
problemStorage := storage.NewProblemStorage(db, logger)
problemService := services.NewProblemService(problemStorage, pandocClient)
userStorage := storage.NewUserStorage(db)
userService := services.NewUserService(userStorage)
permissionService := services.NewPermissionService()
server := transport.NewTesterServer(problemService, sessionClient, permissionService, userService, logger)
lis, err := net.Listen("tcp", cfg.Address)
if err != nil {
panic(err)
}
go func() {
if err := server.Start(lis); err != nil {
logger.Fatal("error starting server", zap.Error(err))
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)
<-stop
}