From 8d01144d8b0fc3e090564d02669ebdcd60b1facd Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Tue, 20 Sep 2022 16:42:57 +0800 Subject: [PATCH] feat: add problem service --- internal/e/code.go | 6 ++++-- internal/repo/model/Problem.go | 14 +++++++++++++ internal/repo/postgresql/postgresql.go | 1 + internal/service/problem/create.go | 19 +++++++++++++++++ internal/service/problem/query.go | 23 ++++++++++++++++++++ internal/service/problem/queryFuzz.go | 25 ++++++++++++++++++++++ internal/service/problem/service.go | 29 ++++++++++++++++++++++++++ internal/service/user/profile.go | 4 ++-- 8 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 internal/repo/model/Problem.go create mode 100644 internal/service/problem/create.go create mode 100644 internal/service/problem/query.go create mode 100644 internal/service/problem/queryFuzz.go create mode 100644 internal/service/problem/service.go diff --git a/internal/e/code.go b/internal/e/code.go index 91bfe00..37e90ca 100644 --- a/internal/e/code.go +++ b/internal/e/code.go @@ -8,6 +8,7 @@ const ( InvalidParameter Status = 101 NotFound Status = 102 DatabaseError Status = 103 + RedisError Status = 104 TokenUnknown Status = 200 TokenEmpty Status = 201 @@ -24,7 +25,7 @@ const ( UserUnauthorized Status = 304 UserDisabled Status = 305 - RedisError Status = 400 + ProblemNotFound Status = 500 ) var msgText = map[Status]string{ @@ -35,6 +36,7 @@ var msgText = map[Status]string{ InvalidParameter: "Invalid Parameter", NotFound: "Not Found", DatabaseError: "Database Error", + RedisError: "Redis Error", TokenUnknown: "Unknown Error (Token)", TokenEmpty: "Token Empty", @@ -51,5 +53,5 @@ var msgText = map[Status]string{ UserUnauthorized: "User Unauthorized", UserDisabled: "User Disabled", - RedisError: "Redis Error", + ProblemNotFound: "Problem Not Found", } diff --git a/internal/repo/model/Problem.go b/internal/repo/model/Problem.go new file mode 100644 index 0000000..bc5adfe --- /dev/null +++ b/internal/repo/model/Problem.go @@ -0,0 +1,14 @@ +package model + +import "gorm.io/gorm" + +type Problem struct { + gorm.Model `json:"-"` + Title string `json:"title" gorm:"not null"` + Content string `json:"content" gorm:"not null"` + TimeLimit uint `json:"time_limit" gorm:"not null"` + MemoryLimit uint `json:"memory_limit" gorm:"not null"` + ProviderID uint `json:"provider_id" gorm:"not null;index"` + Provider User `json:"provider" gorm:"foreignKey:ProviderID"` + IsEnabled bool `json:"is_enabled" gorm:"not null;index"` +} diff --git a/internal/repo/postgresql/postgresql.go b/internal/repo/postgresql/postgresql.go index 1181a77..54470fb 100644 --- a/internal/repo/postgresql/postgresql.go +++ b/internal/repo/postgresql/postgresql.go @@ -82,6 +82,7 @@ func (r *Repo) migrateDatabase() { r.log.Info("Auto Migrating database...") _ = r.db.AutoMigrate(&model.User{}) + _ = r.db.AutoMigrate(&model.Problem{}) } // checkAlive deprecated diff --git a/internal/service/problem/create.go b/internal/service/problem/create.go new file mode 100644 index 0000000..972cc5c --- /dev/null +++ b/internal/service/problem/create.go @@ -0,0 +1,19 @@ +package problem + +import ( + "github.com/WHUPRJ/woj-server/internal/e" + "github.com/WHUPRJ/woj-server/internal/repo/model" + "go.uber.org/zap" +) + +func (s *service) Create(uid uint, problem *model.Problem) (*model.Problem, e.Status) { + problem.ProviderID = uid + problem.IsEnabled = true + + if err := s.db.Create(problem).Error; err != nil { + s.log.Debug("create problem error", zap.Error(err), zap.Any("problem", problem)) + return nil, e.DatabaseError + } + + return problem, e.Success +} diff --git a/internal/service/problem/query.go b/internal/service/problem/query.go new file mode 100644 index 0000000..264f87a --- /dev/null +++ b/internal/service/problem/query.go @@ -0,0 +1,23 @@ +package problem + +import ( + "errors" + "github.com/WHUPRJ/woj-server/internal/e" + "github.com/WHUPRJ/woj-server/internal/repo/model" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +func (s *service) Query(problemId uint) (*model.Problem, e.Status) { + problem := new(model.Problem) + + err := s.db.Preload(clause.Associations).First(&problem, problemId).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, e.ProblemNotFound + } + if err != nil { + return nil, e.DatabaseError + } + + return problem, e.Success +} diff --git a/internal/service/problem/queryFuzz.go b/internal/service/problem/queryFuzz.go new file mode 100644 index 0000000..b09da9a --- /dev/null +++ b/internal/service/problem/queryFuzz.go @@ -0,0 +1,25 @@ +package problem + +import ( + "errors" + "github.com/WHUPRJ/woj-server/internal/e" + "github.com/WHUPRJ/woj-server/internal/repo/model" + "gorm.io/gorm" +) + +func (s *service) QueryFuzz(search string) ([]*model.Problem, e.Status) { + var problems []*model.Problem + + err := s.db. + Where("title LIKE ?", "%"+search+"%"). + Or("content LIKE ?", "%"+search+"%"). + Find(&problems).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, e.ProblemNotFound + } + if err != nil { + return nil, e.DatabaseError + } + + return problems, e.Success +} diff --git a/internal/service/problem/service.go b/internal/service/problem/service.go new file mode 100644 index 0000000..6911eca --- /dev/null +++ b/internal/service/problem/service.go @@ -0,0 +1,29 @@ +package problem + +import ( + "github.com/WHUPRJ/woj-server/internal/e" + "github.com/WHUPRJ/woj-server/internal/global" + "github.com/WHUPRJ/woj-server/internal/repo/model" + "go.uber.org/zap" + "gorm.io/gorm" +) + +var _ Service = (*service)(nil) + +type Service interface { + Create(uint, *model.Problem) (*model.Problem, e.Status) + Query(uint) (*model.Problem, e.Status) + QueryFuzz(string) ([]*model.Problem, e.Status) +} + +type service struct { + log *zap.Logger + db *gorm.DB +} + +func NewProblemService(g *global.Global) Service { + return &service{ + log: g.Log, + db: g.Db.Get().(*gorm.DB), + } +} diff --git a/internal/service/user/profile.go b/internal/service/user/profile.go index 07709db..6577242 100644 --- a/internal/service/user/profile.go +++ b/internal/service/user/profile.go @@ -12,10 +12,10 @@ func (s *service) Profile(id uint) (*model.User, e.Status) { err := s.db.First(&user, id).Error if errors.Is(err, gorm.ErrRecordNotFound) { - return user, e.UserNotFound + return nil, e.UserNotFound } if err != nil { - return user, e.DatabaseError + return nil, e.DatabaseError } return user, e.Success