From 2bc2bf45c72c37d547eb779256af77b7c4667f7f Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Mon, 2 Mar 2026 02:50:43 +0700 Subject: [PATCH] add db module --- cmd/evening_detective/main.go | 8 +- internal/modules/db/interface.go | 27 ++++ .../repository.go => modules/db/service.go} | 150 +++++++++--------- internal/services/services.go | 35 ++-- 4 files changed, 125 insertions(+), 95 deletions(-) create mode 100644 internal/modules/db/interface.go rename internal/{services/repository.go => modules/db/service.go} (63%) diff --git a/cmd/evening_detective/main.go b/cmd/evening_detective/main.go index f7b0cd1..b27b0a0 100644 --- a/cmd/evening_detective/main.go +++ b/cmd/evening_detective/main.go @@ -6,6 +6,7 @@ import ( "evening_detective/internal/app" "evening_detective/internal/config" "evening_detective/internal/modules/cleaner" + "evening_detective/internal/modules/db" "evening_detective/internal/modules/formatter" "evening_detective/internal/modules/link" "evening_detective/internal/modules/password" @@ -41,9 +42,10 @@ func main() { s := grpc.NewServer() // Attach the Greeter service to the server dbFilepath := config.GetDBFilepath() - repository, err := services.NewRepository(dbFilepath) + + dbService, err := db.NewDBService(dbFilepath) if err != nil { - panic(err) + log.Fatalln(err) } cleaner := cleaner.NewCleaner() @@ -68,7 +70,7 @@ func main() { s, app.NewServer( services.NewServices( - repository, + dbService, storyService, linkService, passwordGenerator, diff --git a/internal/modules/db/interface.go b/internal/modules/db/interface.go new file mode 100644 index 0000000..7ae2578 --- /dev/null +++ b/internal/modules/db/interface.go @@ -0,0 +1,27 @@ +package db + +import ( + "context" + "evening_detective/internal/models" +) + +type IDBService interface { + Close() + + GetTeams(ctx context.Context) ([]*models.Team, error) + GetTeam(ctx context.Context, teamId any, password any) (*models.Team, error) + AddTeams(ctx context.Context, teams []*models.Team) ([]*models.Team, error) + DeleteAllTeams(ctx context.Context) error + + GetActions(ctx context.Context, teamId int64) ([]*models.Action, error) + AddActions(ctx context.Context, teamId int64, actions []*models.Action) error + + GetApplications(ctx context.Context, teamId int64) ([]*models.Application, error) + GetApplicationsByState(ctx context.Context, teamId int64, state string) ([]*models.Application, error) + AddApplications(ctx context.Context, teamId int64, applications []*models.Application) error + + GiveApplications(ctx context.Context, teamId int64, applications []*models.Application) error + + GetGame(ctx context.Context) (*models.Game, error) + UpdateGameState(ctx context.Context, state string) error +} diff --git a/internal/services/repository.go b/internal/modules/db/service.go similarity index 63% rename from internal/services/repository.go rename to internal/modules/db/service.go index 8d5b930..5978c4c 100644 --- a/internal/services/repository.go +++ b/internal/modules/db/service.go @@ -1,4 +1,4 @@ -package services +package db import ( "context" @@ -10,11 +10,11 @@ import ( _ "github.com/mattn/go-sqlite3" ) -type Repository struct { +type service struct { db *sql.DB } -func NewRepository(filepath string) (*Repository, error) { +func NewDBService(filepath string) (IDBService, error) { db, err := sql.Open("sqlite3", filepath) if err != nil { return nil, err @@ -36,15 +36,15 @@ func NewRepository(filepath string) (*Repository, error) { if err != nil { return nil, err } - return &Repository{db: db}, nil + return &service{db: db}, nil } -func (r *Repository) Close() { - r.db.Close() +func (s *service) Close() { + s.db.Close() } -func (r *Repository) GetTeams(ctx context.Context) ([]*models.Team, error) { - rows, err := r.db.Query("select id, name, password from teams") +func (s *service) GetTeams(ctx context.Context) ([]*models.Team, error) { + rows, err := s.db.Query("select id, name, password from teams") if err != nil { return nil, err } @@ -62,51 +62,8 @@ func (r *Repository) GetTeams(ctx context.Context) ([]*models.Team, error) { 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 -} - -func (r *Repository) GetActions(ctx context.Context, teamId int64) ([]*models.Action, error) { - rows, err := r.db.Query("select id, place from actions where teamId = $1", teamId) - if err != nil { - return nil, err - } - defer rows.Close() - actions := []*models.Action{} - - for rows.Next() { - item := &models.Action{} - err := rows.Scan(&item.ID, &item.Place) - if err != nil { - return nil, err - } - actions = append(actions, item) - } - return actions, nil -} - -func (r *Repository) AddActions(ctx context.Context, teamId int64, actions []*models.Action) error { - for _, action := range actions { - _, err := r.db.Exec("insert into actions (place, teamId) values ($1, $2)", action.Place, teamId) - if err != nil { - return err - } - } - return nil -} - -func (r *Repository) GetTeam(ctx context.Context, teamId any, password any) (*models.Team, error) { - rows, err := r.db.Query("select id, name from teams where LOWER(name) = LOWER($1) and password = $2", teamId, password) +func (s *service) GetTeam(ctx context.Context, teamId any, password any) (*models.Team, error) { + rows, err := s.db.Query("select id, name from teams where LOWER(name) = LOWER($1) and password = $2", teamId, password) if err != nil { return nil, err } @@ -127,9 +84,47 @@ func (r *Repository) GetTeam(ctx context.Context, teamId any, password any) (*mo return teams[0], nil } -func (r *Repository) AddApplications(ctx context.Context, teamId int64, applications []*models.Application) error { - for _, application := range applications { - _, err := r.db.Exec("insert into applications (name, teamId, state) values ($1, $2, $3)", application.Name, teamId, application.State) +func (s *service) AddTeams(ctx context.Context, teams []*models.Team) ([]*models.Team, error) { + for _, team := range teams { + result, err := s.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 +} + +func (s *service) DeleteAllTeams(ctx context.Context) error { + _, err := s.db.Exec("delete from teams where 1") + return err +} + +func (s *service) GetActions(ctx context.Context, teamId int64) ([]*models.Action, error) { + rows, err := s.db.Query("select id, place from actions where teamId = $1", teamId) + if err != nil { + return nil, err + } + defer rows.Close() + actions := []*models.Action{} + + for rows.Next() { + item := &models.Action{} + err := rows.Scan(&item.ID, &item.Place) + if err != nil { + return nil, err + } + actions = append(actions, item) + } + return actions, nil +} + +func (s *service) AddActions(ctx context.Context, teamId int64, actions []*models.Action) error { + for _, action := range actions { + _, err := s.db.Exec("insert into actions (place, teamId) values ($1, $2)", action.Place, teamId) if err != nil { return err } @@ -137,8 +132,8 @@ func (r *Repository) AddApplications(ctx context.Context, teamId int64, applicat return nil } -func (r *Repository) GetApplications(ctx context.Context, teamId int64) ([]*models.Application, error) { - rows, err := r.db.Query("select id, name from applications where teamId = $1", teamId) +func (s *service) GetApplications(ctx context.Context, teamId int64) ([]*models.Application, error) { + rows, err := s.db.Query("select id, name from applications where teamId = $1", teamId) if err != nil { return nil, err } @@ -156,8 +151,8 @@ func (r *Repository) GetApplications(ctx context.Context, teamId int64) ([]*mode return applications, nil } -func (r *Repository) GetApplicationsByState(ctx context.Context, teamId int64, state string) ([]*models.Application, error) { - rows, err := r.db.Query("select id, name from applications where teamId = $1 and state = $2", teamId, state) +func (s *service) GetApplicationsByState(ctx context.Context, teamId int64, state string) ([]*models.Application, error) { + rows, err := s.db.Query("select id, name from applications where teamId = $1 and state = $2", teamId, state) if err != nil { return nil, err } @@ -175,9 +170,9 @@ func (r *Repository) GetApplicationsByState(ctx context.Context, teamId int64, s return applications, nil } -func (r *Repository) GiveApplications(ctx context.Context, teamId int64, applications []*models.Application) error { +func (s *service) AddApplications(ctx context.Context, teamId int64, applications []*models.Application) error { for _, application := range applications { - _, err := r.db.Exec("update applications set state = \"gave\" where teamId = $1 and id = $2", teamId, application.ID) + _, err := s.db.Exec("insert into applications (name, teamId, state) values ($1, $2, $3)", application.Name, teamId, application.State) if err != nil { return err } @@ -185,8 +180,18 @@ func (r *Repository) GiveApplications(ctx context.Context, teamId int64, applica return nil } -func (r *Repository) GetGame(ctx context.Context) (*models.Game, error) { - rows, err := r.db.Query("select state, startAt, endAt from games limit 1") +func (s *service) GiveApplications(ctx context.Context, teamId int64, applications []*models.Application) error { + for _, application := range applications { + _, err := s.db.Exec("update applications set state = \"gave\" where teamId = $1 and id = $2", teamId, application.ID) + if err != nil { + return err + } + } + return nil +} + +func (s *service) GetGame(ctx context.Context) (*models.Game, error) { + rows, err := s.db.Query("select state, startAt, endAt from games limit 1") if err != nil { return nil, err } @@ -202,7 +207,7 @@ func (r *Repository) GetGame(ctx context.Context) (*models.Game, error) { } state := "NEW" - _, err = r.db.Exec("insert into games (state, startAt, endAt) values ($1, '', '')", state) + _, err = s.db.Exec("insert into games (state, startAt, endAt) values ($1, '', '')", state) if err != nil { return nil, err } @@ -210,27 +215,22 @@ func (r *Repository) GetGame(ctx context.Context) (*models.Game, error) { return game, nil } -func (r *Repository) GameUpdateState(ctx context.Context, state string) error { - game, err := r.GetGame(ctx) +func (s *service) UpdateGameState(ctx context.Context, state string) error { + game, err := s.GetGame(ctx) if err != nil { return err } switch state { case "RUN": if game.StartTime == "" { - _, err := r.db.Exec("update games set state = $1, startAt = datetime('now', 'localtime')", state) + _, err := s.db.Exec("update games set state = $1, startAt = datetime('now', 'localtime')", state) return err } - _, err := r.db.Exec("update games set state = $1", state) + _, err := s.db.Exec("update games set state = $1", state) return err case "STOP": - _, err := r.db.Exec("update games set state = $1, endAt = datetime('now', 'localtime')", state) + _, err := s.db.Exec("update games set state = $1, endAt = datetime('now', 'localtime')", state) return err } return nil } - -func (r *Repository) DeleteAllTeams(ctx context.Context) error { - _, err := r.db.Exec("delete from teams where 1") - return err -} diff --git a/internal/services/services.go b/internal/services/services.go index 63fc1d9..ecb69e4 100644 --- a/internal/services/services.go +++ b/internal/services/services.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/json" "evening_detective/internal/models" + "evening_detective/internal/modules/db" "evening_detective/internal/modules/link" "evening_detective/internal/modules/password" "evening_detective/internal/modules/pdf" @@ -19,7 +20,7 @@ import ( ) type Services struct { - repository *Repository + dbService db.IDBService storyService *story_service.StoryService linkService link.ILinkService passwordGenerator password.IPasswordGenerator @@ -28,7 +29,7 @@ type Services struct { } func NewServices( - repository *Repository, + dbService db.IDBService, storyService *story_service.StoryService, linkService link.ILinkService, passwordGenerator password.IPasswordGenerator, @@ -36,7 +37,7 @@ func NewServices( clientHost string, ) *Services { return &Services{ - repository: repository, + dbService: dbService, storyService: storyService, linkService: linkService, passwordGenerator: passwordGenerator, @@ -47,14 +48,14 @@ func NewServices( func (s *Services) GiveApplications(ctx context.Context, req *proto.GiveApplicationsReq) (*proto.GiveApplicationsRsp, error) { applications := mapProtoApplicationsToApplications(req.Applications) - if err := s.repository.GiveApplications(ctx, req.TeamId, applications); err != nil { + if err := s.dbService.GiveApplications(ctx, req.TeamId, applications); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } return &proto.GiveApplicationsRsp{}, nil } func (s *Services) GetGame(ctx context.Context, _ *proto.GetGameReq) (*proto.GetGameRsp, error) { - game, err := s.repository.GetGame(ctx) + game, err := s.dbService.GetGame(ctx) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } @@ -66,14 +67,14 @@ func (s *Services) GetGame(ctx context.Context, _ *proto.GetGameReq) (*proto.Get } func (s *Services) GameStart(ctx context.Context, _ *proto.GameStartReq) (*proto.GameStartRsp, error) { - if err := s.repository.GameUpdateState(ctx, "RUN"); err != nil { + if err := s.dbService.UpdateGameState(ctx, "RUN"); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } return &proto.GameStartRsp{}, nil } func (s *Services) GameStop(ctx context.Context, req *proto.GameStopReq) (*proto.GameStopRsp, error) { - if err := s.repository.GameUpdateState(ctx, "STOP"); err != nil { + if err := s.dbService.UpdateGameState(ctx, "STOP"); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } return &proto.GameStopRsp{}, nil @@ -92,10 +93,10 @@ func (s *Services) AddAction(ctx context.Context, req *proto.AddActionReq) (*pro Applications: mapStoryApplicationsToApplications(place.Applications), }, } - if err := s.repository.AddActions(ctx, team.ID, actions); err != nil { + if err := s.dbService.AddActions(ctx, team.ID, actions); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } - currentApplications, err := s.repository.GetApplications(ctx, team.ID) + currentApplications, err := s.dbService.GetApplications(ctx, team.ID) if err != nil { return nil, err } @@ -115,7 +116,7 @@ func (s *Services) AddAction(ctx context.Context, req *proto.AddActionReq) (*pro } } - if err := s.repository.AddApplications(ctx, team.ID, newApplications); err != nil { + if err := s.dbService.AddApplications(ctx, team.ID, newApplications); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } addLog(team, "add action", actions) @@ -128,7 +129,7 @@ func (s *Services) GetTeam(ctx context.Context, req *proto.GetTeamReq) (*proto.G return nil, err } - actions, err := s.repository.GetActions(ctx, team.ID) + actions, err := s.dbService.GetActions(ctx, team.ID) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } @@ -155,20 +156,20 @@ func (s *Services) GetTeamsCSV(ctx context.Context, req *proto.GetTeamsCSVReq) ( } func (s *Services) GetTeams(ctx context.Context, _ *proto.GetTeamsReq) (*proto.GetTeamsRsp, error) { - teams, err := s.repository.GetTeams(ctx) + teams, err := s.dbService.GetTeams(ctx) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } res := make([]*proto.TeamAdvanced, 0, len(teams)) for _, team := range teams { newTeam := mapTeamsToTeamAdvanced(team) - actions, err := s.repository.GetActions(ctx, team.ID) + actions, err := s.dbService.GetActions(ctx, team.ID) if err != nil { return nil, err } newTeam.Url = s.linkService.GetTeamClientLink(s.clientHost, team.Name, team.Password) newTeam.SpendTime = int64(len(actions)) - currentApplications, err := s.repository.GetApplicationsByState(ctx, team.ID, "NEW") + currentApplications, err := s.dbService.GetApplicationsByState(ctx, team.ID, "NEW") if err != nil { return nil, err } @@ -185,7 +186,7 @@ func (s *Services) AddTeams(ctx context.Context, req *proto.AddTeamsReq) (*proto t.Password = s.passwordGenerator.GeneratePassword(8) inTeams = append(inTeams, t) } - teams, err := s.repository.AddTeams(ctx, inTeams) + teams, err := s.dbService.AddTeams(ctx, inTeams) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } @@ -199,7 +200,7 @@ func (s *Services) AddTeams(ctx context.Context, req *proto.AddTeamsReq) (*proto func (s *Services) DownloadTeamsQrCodesFile(ctx context.Context, req *proto.DownloadTeamsQrCodesFileReq) (*proto.DownloadTeamsQrCodesFileRsp, error) { ctx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() - teams, err := s.repository.GetTeams(ctx) + teams, err := s.dbService.GetTeams(ctx) if err != nil { return nil, err } @@ -293,7 +294,7 @@ func (s *Services) getTeam(ctx context.Context) (*models.Team, error) { } password := passwordArr[0] - team, err := s.repository.GetTeam(ctx, teamId, password) + team, err := s.dbService.GetTeam(ctx, teamId, password) if err != nil { return nil, status.Errorf(codes.Unauthenticated, err.Error()) }