This commit is contained in:
Владимир Фёдоров 2025-05-17 04:36:06 +07:00
parent 8643af86ee
commit 4bd18ee756
13 changed files with 188 additions and 7 deletions

View File

@ -1,5 +1,6 @@
{ {
"cSpell.words": [ "cSpell.words": [
"AUTOINCREMENT",
"gwmux" "gwmux"
] ]
} }

16
api/requests.http Normal file
View File

@ -0,0 +1,16 @@
GET http://localhost:8090/teams
###
POST http://localhost:8090/teams
{
"teams": [
{
"name": "Облако"
},
{
"name": "Кустик"
}
]
}

View File

@ -24,10 +24,14 @@ func main() {
// Create a gRPC server object // Create a gRPC server object
s := grpc.NewServer() s := grpc.NewServer()
// Attach the Greeter service to the server // Attach the Greeter service to the server
repository, err := services.NewRepository()
if err != nil {
panic(err)
}
proto.RegisterEveningDetectiveServer( proto.RegisterEveningDetectiveServer(
s, s,
app.NewServer( app.NewServer(
services.NewServices(), services.NewServices(repository),
), ),
) )
// Serve gRPC server // Serve gRPC server

1
go.mod
View File

@ -8,6 +8,7 @@ require (
) )
require ( require (
github.com/mattn/go-sqlite3 v1.14.28
golang.org/x/net v0.23.0 // indirect golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.15.0 // indirect golang.org/x/text v0.15.0 // indirect

View File

@ -0,0 +1,7 @@
package models
type Action struct {
ID string
To string
Time int64
}

View File

@ -0,0 +1,7 @@
package models
type Application struct {
TeamID int64
Name string
State string
}

7
internal/models/game.go Normal file
View File

@ -0,0 +1,7 @@
package models
type Game struct {
StartTime int64
EndTime int64
State string
}

7
internal/models/team.go Normal file
View File

@ -0,0 +1,7 @@
package models
type Team struct {
ID int64
Name string
Password string
}

View File

@ -0,0 +1,15 @@
package password
import "math/rand"
var (
letters = []rune("abcdefghijklmnopqrstuvwxyz123456789")
)
func GenPass(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}

View File

@ -0,0 +1,27 @@
package services
import (
"evening_detective/internal/models"
"evening_detective/proto"
)
func mapTeamsToTeamAdvanced(team *models.Team) *proto.TeamAdvanced {
return &proto.TeamAdvanced{
Id: team.ID,
Name: team.Name,
}
}
func mapTeamsToTeamFull(team *models.Team) *proto.TeamFull {
return &proto.TeamFull{
Id: team.ID,
Name: team.Name,
Password: team.Password,
}
}
func mapProtoTeamsToTeam(team *proto.Team) *models.Team {
return &models.Team{
Name: team.Name,
}
}

View File

@ -0,0 +1,58 @@
package services
import (
"context"
"database/sql"
"evening_detective/internal/models"
_ "github.com/mattn/go-sqlite3"
)
type Repository struct {
db *sql.DB
}
func NewRepository() (*Repository, error) {
db, err := sql.Open("sqlite3", "store.db")
if err != nil {
return nil, err
}
_, err = db.Exec("CREATE TABLE IF NOT EXISTS teams (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, password TEXT);")
if err != nil {
return nil, err
}
return &Repository{db: db}, nil
}
func (r *Repository) GetTeams(ctx context.Context) ([]*models.Team, error) {
rows, err := r.db.Query("select id, name, password from teams")
if err != nil {
panic(err)
}
defer rows.Close()
teams := []*models.Team{}
for rows.Next() {
team := &models.Team{}
err := rows.Scan(&team.ID, &team.Name, &team.Password)
if err != nil {
return nil, err
}
teams = append(teams, team)
}
return teams, nil
}
func (r *Repository) AddTeams(ctx context.Context, teams []*models.Team) ([]*models.Team, error) {
for _, team := range teams {
result, err := r.db.Exec("insert into teams (name, password) values ($1, $2)", team.Name, team.Password)
if err != nil {
return nil, err
}
team.ID, err = result.LastInsertId()
if err != nil {
return nil, err
}
}
return teams, nil
}

View File

@ -2,13 +2,22 @@ package services
import ( import (
"context" "context"
"evening_detective/internal/models"
"evening_detective/internal/modules/password"
"evening_detective/proto" "evening_detective/proto"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
type Services struct{} type Services struct {
repository *Repository
}
func NewServices() *Services { func NewServices(repository *Repository) *Services {
return &Services{} return &Services{
repository: repository,
}
} }
func (s *Services) GiveApplications(ctx context.Context, req *proto.GiveApplicationsReq) (*proto.GiveApplicationsRsp, error) { func (s *Services) GiveApplications(ctx context.Context, req *proto.GiveApplicationsReq) (*proto.GiveApplicationsRsp, error) {
@ -39,10 +48,32 @@ func (s *Services) GetTeamsCSV(ctx context.Context, req *proto.GetTeamsCSVReq) (
panic("unimplemented") panic("unimplemented")
} }
func (s *Services) GetTeams(ctx context.Context, req *proto.GetTeamsReq) (*proto.GetTeamsRsp, error) { func (s *Services) GetTeams(ctx context.Context, _ *proto.GetTeamsReq) (*proto.GetTeamsRsp, error) {
panic("unimplemented") teams, err := s.repository.GetTeams(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
res := make([]*proto.TeamAdvanced, 0, len(teams))
for _, team := range teams {
res = append(res, mapTeamsToTeamAdvanced(team))
}
return &proto.GetTeamsRsp{Teams: res}, err
} }
func (s *Services) AddTeams(ctx context.Context, req *proto.AddTeamsReq) (*proto.AddTeamsRsp, error) { func (s *Services) AddTeams(ctx context.Context, req *proto.AddTeamsReq) (*proto.AddTeamsRsp, error) {
panic("unimplemented") inTeams := make([]*models.Team, 0, len(req.Teams))
for _, team := range req.Teams {
t := mapProtoTeamsToTeam(team)
t.Password = password.GenPass(8)
inTeams = append(inTeams, t)
}
teams, err := s.repository.AddTeams(ctx, inTeams)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
res := make([]*proto.TeamFull, 0, len(teams))
for _, team := range teams {
res = append(res, mapTeamsToTeamFull(team))
}
return &proto.AddTeamsRsp{Teams: res}, err
} }

BIN
store.db Normal file

Binary file not shown.