clean up
This commit is contained in:
69
handlers_v2/cage_handler.go
Normal file
69
handlers_v2/cage_handler.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/storage/validators"
|
||||
"hamster-tycoon/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (hc *handlersContext) getAllCages(c *gin.Context) {
|
||||
gameID := c.Param("gameID")
|
||||
err := hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
cages, err := hc.db.GetAllCages(gameID)
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting cages")
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting cages")
|
||||
return
|
||||
}
|
||||
utils.JSON(c.Writer, http.StatusOK, cages)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) getACage(c *gin.Context) {
|
||||
cageID := c.Param("cageID")
|
||||
gameID := c.Param("gameID")
|
||||
|
||||
err := hc.validator.VarCtx(c, cageID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
cage, err := hc.db.GetCageByID(gameID, cageID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Cage not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetCage: get cage error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get cage")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
if cage == nil {
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Cage not found")
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusOK, cage)
|
||||
}
|
||||
207
handlers_v2/hamster_handler.go
Normal file
207
handlers_v2/hamster_handler.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/gin-gonic/gin"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/storage/validators"
|
||||
"hamster-tycoon/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (hc *handlersContext) getAllHamsters(c *gin.Context) {
|
||||
gameID := c.Param("gameID")
|
||||
cageID := c.Param("cageID")
|
||||
|
||||
err := hc.validator.VarCtx(c, cageID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
hamsters, err := hc.db.GetAllHamsters(gameID, cageID)
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting hamsters")
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting hamsters")
|
||||
return
|
||||
}
|
||||
utils.JSON(c.Writer, http.StatusOK, hamsters)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) getAHamster(c *gin.Context) {
|
||||
gameID := c.Param("gameID")
|
||||
cageID := c.Param("cageID")
|
||||
hamsterID := c.Param("hamsterID")
|
||||
|
||||
err := hc.validator.VarCtx(c, cageID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, hamsterID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
hamster, err := hc.db.GetHamsterByID(hamsterID, gameID, cageID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetHamster: get hamster error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get hamster")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
if hamster == nil {
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster not found")
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusOK, hamster)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) createAHamster(c *gin.Context) {
|
||||
gameID := c.Param("gameID")
|
||||
cageID := c.Param("cageID")
|
||||
|
||||
err := hc.validator.VarCtx(c, cageID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
b, err := c.GetRawData()
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating hamster, read data fail")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
hamsterToCreate := model.Hamster{}
|
||||
err = json.Unmarshal(b, &hamsterToCreate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.StructCtx(c, hamsterToCreate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
hamsterToCreate.Cage = &model.Cage{ID: cageID, Game: model.Game{ID: gameID}}
|
||||
err = hc.db.CreateHamster(&hamsterToCreate)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeDuplicate:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrAlreadyExists, "Hamster already exists")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error CreateHamster: Error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating hamster")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusCreated, hamsterToCreate)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) updateAHamster(c *gin.Context) {
|
||||
panic("TO DO")
|
||||
}
|
||||
|
||||
func (hc *handlersContext) deleteAHamster(c *gin.Context) {
|
||||
hamsterID := c.Param("hamsterID")
|
||||
gameID := c.Param("gameID")
|
||||
cageID := c.Param("cageID")
|
||||
|
||||
err := hc.validator.VarCtx(c, cageID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, gameID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.VarCtx(c, hamsterID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
// check hamster id given in URL exists
|
||||
_, err = hc.db.GetHamsterByID(hamsterID, gameID, cageID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster to delete not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteHamster: get hamster error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get hamster to delete")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.db.DeleteHamster(hamsterID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster to delete not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteHamster: Error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting hamster")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusNoContent, nil)
|
||||
|
||||
}
|
||||
126
handlers_v2/handler.go
Executable file
126
handlers_v2/handler.go
Executable file
@@ -0,0 +1,126 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"hamster-tycoon/middlewares"
|
||||
"hamster-tycoon/service"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/dao/fake"
|
||||
"hamster-tycoon/storage/dao/postgresql"
|
||||
"hamster-tycoon/storage/validators"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Mock bool
|
||||
DBConnectionURI string
|
||||
Port int
|
||||
LogLevel string
|
||||
LogFormat string
|
||||
}
|
||||
|
||||
type handlersContext struct {
|
||||
db dao.Database
|
||||
validator *validator.Validate
|
||||
userService *service.UserService
|
||||
gameService *service.GameService
|
||||
cageService *service.CageService
|
||||
hamsterService *service.HamsterService
|
||||
}
|
||||
|
||||
func NewRouter(config *Config) *gin.Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
router := gin.New()
|
||||
router.HandleMethodNotAllowed = true
|
||||
|
||||
router.Use(cors.New(cors.Config{
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowMethods: []string{"*"},
|
||||
AllowHeaders: []string{"*"},
|
||||
ExposeHeaders: []string{"*"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}))
|
||||
router.Use(gin.Recovery())
|
||||
router.Use(middlewares.GetLoggerMiddleware())
|
||||
router.Use(middlewares.GetHTTPLoggerMiddleware())
|
||||
|
||||
hc := &handlersContext{}
|
||||
if config.Mock {
|
||||
hc.db = fake.NewDatabaseFake()
|
||||
} else {
|
||||
hc.db = postgresql.NewDatabasePostgreSQL(config.DBConnectionURI)
|
||||
}
|
||||
hc.validator = newValidator()
|
||||
hc.userService = service.NewUserService(hc.db)
|
||||
hc.gameService = service.NewGameService(hc.db)
|
||||
hc.cageService = service.NewCageService(hc.db)
|
||||
hc.hamsterService = service.NewHamsterService(hc.db)
|
||||
|
||||
public := router.Group("/")
|
||||
public.Handle(http.MethodGet, "/_health", hc.GetHealth)
|
||||
|
||||
userRoute := public.Group("/users")
|
||||
userRoute.Handle("LOGIN", "", hc.connectUser)
|
||||
userRoute.Handle(http.MethodPost, "", hc.createUser)
|
||||
|
||||
securedUserRoute := userRoute.Group("")
|
||||
//TODO add secure auth
|
||||
securedUserRoute.Handle(http.MethodGet, "", hc.getAllUsers)
|
||||
securedUserRoute.Handle(http.MethodGet, "/:userID", hc.getUser)
|
||||
securedUserRoute.Handle(http.MethodPut, "/:userID", hc.updateUser)
|
||||
securedUserRoute.Handle(http.MethodDelete, "/:userID", hc.deleteUser)
|
||||
// end: user routes
|
||||
|
||||
gameRoute := securedUserRoute.Group("/:userID/games")
|
||||
gameRoute.Handle(http.MethodGet, "", hc.getAllGames)
|
||||
gameRoute.Handle(http.MethodGet, "/:gameID", hc.getAGame)
|
||||
gameRoute.Handle(http.MethodPost, "/:gameID", hc.createAGame)
|
||||
gameRoute.Handle(http.MethodPut, "/:gameID", hc.updateAGame)
|
||||
gameRoute.Handle(http.MethodGet, "/:gameID/hamsters", hc.getHamstersOfGame)
|
||||
gameRoute.Handle(http.MethodDelete, "/:gameID", hc.deleteAGame)
|
||||
|
||||
cageRoute := gameRoute.Group("/:gameID/cages")
|
||||
cageRoute.Handle(http.MethodGet, "", hc.getAllCages)
|
||||
cageRoute.Handle(http.MethodGet, "/:cageID", hc.getACage)
|
||||
cageRoute.Handle(http.MethodPost, "/:cageID", hc.createACage)
|
||||
cageRoute.Handle(http.MethodPut, "/:cageID", hc.updateACage)
|
||||
cageRoute.Handle(http.MethodDelete, "/:cageID", hc.deleteACage)
|
||||
|
||||
hamsterRoute := cageRoute.Group("/:cageID/hamsters")
|
||||
hamsterRoute.Handle(http.MethodGet, "", hc.getAllHamsters)
|
||||
hamsterRoute.Handle(http.MethodGet, "/:hamsterID", hc.getAHamster)
|
||||
hamsterRoute.Handle(http.MethodPost, "/:hamsterID", hc.createAHamster)
|
||||
hamsterRoute.Handle(http.MethodPut, "/:hamsterID", hc.updateAHamster)
|
||||
hamsterRoute.Handle(http.MethodDelete, "/:hamsterID", hc.deleteAHamster)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
func newValidator() *validator.Validate {
|
||||
va := validator.New()
|
||||
|
||||
va.RegisterTagNameFunc(func(fld reflect.StructField) string {
|
||||
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)
|
||||
if len(name) < 1 {
|
||||
return ""
|
||||
}
|
||||
return name[0]
|
||||
})
|
||||
|
||||
for k, v := range validators.CustomValidators {
|
||||
if v.Validator != nil {
|
||||
va.RegisterValidationCtx(k, v.Validator)
|
||||
}
|
||||
}
|
||||
|
||||
return va
|
||||
}
|
||||
12
handlers_v2/health_handler.go
Executable file
12
handlers_v2/health_handler.go
Executable file
@@ -0,0 +1,12 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"hamster-tycoon/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (hc *handlersContext) GetHealth(c *gin.Context) {
|
||||
utils.JSON(c.Writer, http.StatusNoContent, nil)
|
||||
}
|
||||
268
handlers_v2/user_handler.go
Executable file
268
handlers_v2/user_handler.go
Executable file
@@ -0,0 +1,268 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/storage/validators"
|
||||
"hamster-tycoon/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"google.golang.org/api/oauth2/v2"
|
||||
)
|
||||
|
||||
func (hc *handlersContext) getAllUsers(c *gin.Context) {
|
||||
users, err := hc.db.GetAllUsers()
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting users")
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting users")
|
||||
return
|
||||
}
|
||||
utils.JSON(c.Writer, http.StatusOK, users)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) connectUser(c *gin.Context) {
|
||||
authorizationHeader := c.GetHeader("Authorization")
|
||||
authorizationHeaderSplitted := strings.Split(authorizationHeader, " ")
|
||||
if len(authorizationHeaderSplitted) != 2 {
|
||||
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
|
||||
return
|
||||
}
|
||||
|
||||
oauth2Service, err := oauth2.New(&http.Client{})
|
||||
if oauth2Service == nil {
|
||||
fmt.Println(err)
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
tokenInfoCall := oauth2Service.Tokeninfo()
|
||||
tokenInfoCall.IdToken(authorizationHeaderSplitted[1])
|
||||
tokenInfo, err := tokenInfoCall.Do()
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error(err)
|
||||
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
|
||||
return
|
||||
}
|
||||
user, err := hc.userService.GetUserFromGoogleID(tokenInfo.UserId)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error(err)
|
||||
if castedError, ok := err.(*model.APIError); ok {
|
||||
if castedError.Type == model.ErrNotFound.Type {
|
||||
user, err := hc.userService.CreateUserFromGoogleToken(tokenInfo.UserId, tokenInfo.Email)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
utils.JSON(c.Writer, 200, user)
|
||||
return
|
||||
}
|
||||
utils.JSONError(c.Writer, *castedError)
|
||||
return
|
||||
}
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
fmt.Println("Found the user " + user.Nickname)
|
||||
fmt.Println("Return 200")
|
||||
utils.JSON(c.Writer, 200, user)
|
||||
}
|
||||
func (hc *handlersContext) createUser(c *gin.Context) {
|
||||
b, err := c.GetRawData()
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating user, read data fail")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
userToCreate := model.UserEditable{}
|
||||
err = json.Unmarshal(b, &userToCreate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.StructCtx(c, userToCreate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
user := model.User{
|
||||
UserEditable: userToCreate,
|
||||
}
|
||||
|
||||
err = hc.db.CreateUser(&user)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeDuplicate:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrAlreadyExists, "User already exists")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error CreateUser: Error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating user")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusCreated, user)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) getUser(c *gin.Context) {
|
||||
userID := c.Param("id")
|
||||
|
||||
err := hc.validator.VarCtx(c, userID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := hc.db.GetUsersByID(userID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User not found")
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusOK, user)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) deleteUser(c *gin.Context) {
|
||||
userID := c.Param("id")
|
||||
|
||||
err := hc.validator.VarCtx(c, userID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
// check user id given in URL exists
|
||||
_, err = hc.db.GetUsersByID(userID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to delete not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteUser: get user error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user to delete")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.db.DeleteUser(userID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to delete not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteUser: Error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting user")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
func (hc *handlersContext) updateUser(c *gin.Context) {
|
||||
userID := c.Param("id")
|
||||
|
||||
err := hc.validator.VarCtx(c, userID, "uuid4")
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
// check user id given in URL exists
|
||||
user, err := hc.db.GetUsersByID(userID)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to update not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("deleteUser: get user error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user to update")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
// get body and verify data
|
||||
b, err := c.GetRawData()
|
||||
if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while updating user, read data fail")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
userToUpdate := model.UserEditable{}
|
||||
err = json.Unmarshal(b, &userToUpdate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
|
||||
return
|
||||
}
|
||||
|
||||
err = hc.validator.StructCtx(c, userToUpdate)
|
||||
if err != nil {
|
||||
utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err))
|
||||
return
|
||||
}
|
||||
|
||||
user.UserEditable = userToUpdate
|
||||
|
||||
// make the update
|
||||
err = hc.db.UpdateUser(user)
|
||||
if e, ok := err.(*dao.Error); ok {
|
||||
switch {
|
||||
case e.Type == dao.ErrTypeNotFound:
|
||||
utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to update not found")
|
||||
return
|
||||
default:
|
||||
utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error UpdateUser: Error type not handled")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting user")
|
||||
utils.JSONError(c.Writer, model.ErrInternalServer)
|
||||
return
|
||||
}
|
||||
|
||||
utils.JSON(c.Writer, http.StatusOK, user)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
|
||||
<changeSet id="add-game-name" author="kratisto">
|
||||
<addColumn tableName="game">
|
||||
<column name="name" type="varchar(255)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -14,7 +14,7 @@
|
||||
<column name="updated_at" type="timestamp">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="game_id" type="uuid" >
|
||||
<column name="local_id" type="uuid" >
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
|
||||
<changeSet id="add-game-table" author="kratisto">
|
||||
<createTable tableName="game">
|
||||
<column name="id" type="uuid" defaultValueComputed="gen_random_uuid()">
|
||||
<constraints nullable="false" unique="true"/>
|
||||
</column>
|
||||
<column name="user_id" type="uuid">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_at" type="timestamp" defaultValueComputed="now()">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="updated_at" type="timestamp">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -53,6 +53,9 @@
|
||||
<column name="sold" type="boolean">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="golden" type="boolean">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="gestation" type="boolean">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
)
|
||||
|
||||
type GameService struct {
|
||||
serviceContext
|
||||
}
|
||||
|
||||
func NewGameService(database dao.Database) *GameService {
|
||||
return &GameService{serviceContext{db: database}}
|
||||
}
|
||||
|
||||
func (gs *GameService) GetAGameByID(id string) (*model.Game, error) {
|
||||
game, err := gs.db.GetGameByID(id)
|
||||
if err != nil {
|
||||
if castedError, ok := err.(*dao.Error); ok {
|
||||
switch castedError.Type {
|
||||
case dao.ErrTypeNotFound:
|
||||
return nil, &model.ErrNotFound
|
||||
default:
|
||||
return nil, &model.ErrInternalServer
|
||||
}
|
||||
}
|
||||
return nil, &model.ErrInternalServer
|
||||
}
|
||||
return game, nil
|
||||
}
|
||||
@@ -15,28 +15,19 @@ type Database interface {
|
||||
UpdateUser(*model.User) error
|
||||
// end: user dao funcs
|
||||
|
||||
// start: cage games funcs
|
||||
GetAllGames() ([]*model.Game, error)
|
||||
GetGameByID(string) (*model.Game, error)
|
||||
CreateGame(*model.Game) error
|
||||
DeleteGame(string) error
|
||||
UpdateGame(*model.Game) error
|
||||
// end: games dao funcs
|
||||
|
||||
// start: cage funcs
|
||||
GetAllCages(string) ([]*model.Cage, error)
|
||||
GetCageByID(string, string) (*model.Cage, error)
|
||||
GetAllCages() ([]*model.Cage, error)
|
||||
GetCageByID(string) (*model.Cage, error)
|
||||
CreateCage(*model.Cage) error
|
||||
DeleteCage(string) error
|
||||
UpdateCage(*model.Cage) error
|
||||
// end: cage dao funcs
|
||||
// start: hamster funcs
|
||||
GetAllHamsters(string, string) ([]*model.Hamster, error)
|
||||
GetHamsterByID(string, string, string) (*model.Hamster, error)
|
||||
GetAllHamsters(string) ([]*model.Hamster, error)
|
||||
GetHamsterByID(string, string) (*model.Hamster, error)
|
||||
CreateHamster(*model.Hamster) error
|
||||
DeleteHamster(string) error
|
||||
UpdateHamster(*model.Hamster) error
|
||||
GetHamstersOfGame(string) ([]*model.Hamster, error)
|
||||
// end: hamster dao funcs
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/utils"
|
||||
"time"
|
||||
|
||||
"github.com/allegro/bigcache"
|
||||
)
|
||||
|
||||
type DatabaseFake struct {
|
||||
Cache *bigcache.BigCache
|
||||
}
|
||||
|
||||
func NewDatabaseFake() dao.Database {
|
||||
cache, err := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Fatal("Error while instantiate cache")
|
||||
}
|
||||
return &DatabaseFake{
|
||||
Cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) save(key string, data []interface{}) {
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Errorf("Error while marshal fake %s", key)
|
||||
db.Cache.Set(key, []byte("[]"))
|
||||
return
|
||||
}
|
||||
err = db.Cache.Set(key, b)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Errorf("Error while saving fake %s", key)
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
cacheKeyCages = "cages"
|
||||
)
|
||||
|
||||
func (db *DatabaseFake) saveCages(cages []*model.Cage) {
|
||||
data := make([]interface{}, 0)
|
||||
for _, v := range cages {
|
||||
data = append(data, v)
|
||||
}
|
||||
db.save(cacheKeyCages, data)
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) loadCages() []*model.Cage {
|
||||
cages := make([]*model.Cage, 0)
|
||||
b, err := db.Cache.Get(cacheKeyCages)
|
||||
if err != nil {
|
||||
return cages
|
||||
}
|
||||
err = json.Unmarshal(b, &cages)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error("Error while unmarshal fake users")
|
||||
}
|
||||
return cages
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetAllCages(gameID string) ([]*model.Cage, error) {
|
||||
cages := db.loadCages()
|
||||
var cagesLoaded []*model.Cage
|
||||
for _, g := range cages {
|
||||
if g.Game.ID == gameID {
|
||||
cagesLoaded = append(cagesLoaded, g)
|
||||
}
|
||||
}
|
||||
return cagesLoaded, nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetCageByID(gameID, cageID string) (*model.Cage, error) {
|
||||
cages := db.loadCages()
|
||||
for _, g := range cages {
|
||||
if g.Game.ID == gameID && g.ID == cageID {
|
||||
return g, nil
|
||||
}
|
||||
}
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("cage not found"))
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) CreateCage(cage *model.Cage) error {
|
||||
cage.ID = uuid.NewV4().String()
|
||||
|
||||
cages := db.loadCages()
|
||||
cages = append(cages, cage)
|
||||
db.saveCages(cages)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) DeleteCage(string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) UpdateCage(*model.Cage) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
cacheKeyGames = "games"
|
||||
)
|
||||
|
||||
func (db *DatabaseFake) saveGames(games []*model.Game) {
|
||||
data := make([]interface{}, 0)
|
||||
for _, v := range games {
|
||||
data = append(data, v)
|
||||
}
|
||||
db.save(cacheKeyGames, data)
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) loadGames() []*model.Game {
|
||||
games := make([]*model.Game, 0)
|
||||
b, err := db.Cache.Get(cacheKeyGames)
|
||||
if err != nil {
|
||||
return games
|
||||
}
|
||||
err = json.Unmarshal(b, &games)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error("Error while unmarshal fake users")
|
||||
}
|
||||
return games
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetAllGames() ([]*model.Game, error) {
|
||||
return db.loadGames(), nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetGameByID(gameID string) (*model.Game, error) {
|
||||
games := db.loadGames()
|
||||
for _, g := range games {
|
||||
if g.ID == gameID {
|
||||
return g, nil
|
||||
}
|
||||
}
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("game not found"))
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) CreateGame(game *model.Game) error {
|
||||
game.ID = uuid.NewV4().String()
|
||||
|
||||
games := db.loadGames()
|
||||
games = append(games, game)
|
||||
db.saveGames(games)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) DeleteGame(string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) UpdateGame(*model.Game) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetHamstersOfGame(game string) ([]*model.Hamster, error) {
|
||||
hamsters := db.loadHamsters()
|
||||
var hamstersFound []*model.Hamster
|
||||
for _, g := range hamsters {
|
||||
if g.Cage.Game.ID == game {
|
||||
hamstersFound = append(hamstersFound, g)
|
||||
}
|
||||
}
|
||||
return hamstersFound, nil
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
cacheKeyHamsters = "hamsters"
|
||||
)
|
||||
|
||||
func (db *DatabaseFake) saveHamsters(hamsters []*model.Hamster) {
|
||||
data := make([]interface{}, 0)
|
||||
for _, v := range hamsters {
|
||||
data = append(data, v)
|
||||
}
|
||||
db.save(cacheKeyHamsters, data)
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) loadHamsters() []*model.Hamster {
|
||||
hamsters := make([]*model.Hamster, 0)
|
||||
b, err := db.Cache.Get(cacheKeyHamsters)
|
||||
if err != nil {
|
||||
return hamsters
|
||||
}
|
||||
err = json.Unmarshal(b, &hamsters)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error("Error while unmarshal fake users")
|
||||
}
|
||||
return hamsters
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetAllHamsters(gameID, cageID string) ([]*model.Hamster, error) {
|
||||
hamsters := db.loadHamsters()
|
||||
var hamsterFound []*model.Hamster
|
||||
for _, g := range hamsters {
|
||||
if g.Cage.ID == cageID && g.Cage.Game.ID == gameID {
|
||||
hamsterFound = append(hamsterFound, g)
|
||||
}
|
||||
}
|
||||
return hamsterFound, nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetHamsterByID(hamsterID, gameID, cageID string) (*model.Hamster, error) {
|
||||
hamsters := db.loadHamsters()
|
||||
for _, g := range hamsters {
|
||||
if g.ID == hamsterID && g.Cage.ID == cageID && g.Cage.Game.ID == gameID {
|
||||
return g, nil
|
||||
}
|
||||
}
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("hamster not found"))
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) CreateHamster(hamster *model.Hamster) error {
|
||||
hamster.ID = uuid.NewV4().String()
|
||||
|
||||
hamsters := db.loadHamsters()
|
||||
hamsters = append(hamsters, hamster)
|
||||
db.saveHamsters(hamsters)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) DeleteHamster(string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) UpdateHamster(*model.Hamster) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
"hamster-tycoon/utils"
|
||||
"time"
|
||||
|
||||
"github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
cacheKeyUsers = "users"
|
||||
)
|
||||
|
||||
func (db *DatabaseFake) saveUsers(users []*model.User) {
|
||||
data := make([]interface{}, 0)
|
||||
for _, v := range users {
|
||||
data = append(data, v)
|
||||
}
|
||||
db.save(cacheKeyUsers, data)
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) loadUsers() []*model.User {
|
||||
users := make([]*model.User, 0)
|
||||
b, err := db.Cache.Get(cacheKeyUsers)
|
||||
if err != nil {
|
||||
return users
|
||||
}
|
||||
err = json.Unmarshal(b, &users)
|
||||
if err != nil {
|
||||
utils.GetLogger().WithError(err).Error("Error while unmarshal fake users")
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetAllUsers() ([]*model.User, error) {
|
||||
return db.loadUsers(), nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetUsersByID(userID string) (*model.User, error) {
|
||||
users := db.loadUsers()
|
||||
for _, u := range users {
|
||||
if u.ID == userID {
|
||||
return u, nil
|
||||
}
|
||||
}
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found"))
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) CreateUser(user *model.User) error {
|
||||
user.ID = uuid.NewV4().String()
|
||||
user.CreatedAt = time.Now()
|
||||
|
||||
users := db.loadUsers()
|
||||
users = append(users, user)
|
||||
db.saveUsers(users)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) DeleteUser(userID string) error {
|
||||
users := db.loadUsers()
|
||||
newUsers := make([]*model.User, 0)
|
||||
for _, u := range users {
|
||||
if u.ID != userID {
|
||||
newUsers = append(newUsers, u)
|
||||
}
|
||||
}
|
||||
db.saveUsers(newUsers)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) UpdateUser(user *model.User) error {
|
||||
users := db.loadUsers()
|
||||
var foundUser *model.User
|
||||
for _, u := range users {
|
||||
if u.ID == user.ID {
|
||||
foundUser = u
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if foundUser == nil {
|
||||
return dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found"))
|
||||
}
|
||||
|
||||
foundUser.UserEditable = user.UserEditable
|
||||
now := time.Now()
|
||||
foundUser.UpdatedAt = &now
|
||||
db.saveUsers(users)
|
||||
|
||||
*user = *foundUser
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabaseFake) GetUsersByGoogleID(userID string) (*model.User, error) {
|
||||
users := db.loadUsers()
|
||||
for _, u := range users {
|
||||
if u.GoogleID == userID {
|
||||
return u, nil
|
||||
}
|
||||
}
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found"))
|
||||
}
|
||||
@@ -2,18 +2,18 @@ package postgresql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/lib/pq"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error) {
|
||||
func (db *DatabasePostgreSQL) GetAllCages() ([]*model.Cage, error) {
|
||||
q := `
|
||||
SELECT c.id, created_at, updated_at, game_id
|
||||
SELECT c.id, created_at, updated_at
|
||||
FROM public.Cage c
|
||||
WHERE c.game_id=$1
|
||||
`
|
||||
rows, err := db.session.Query(q, gameID)
|
||||
rows, err := db.session.Query(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -21,11 +21,8 @@ func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error)
|
||||
|
||||
cages := make([]*model.Cage, 0)
|
||||
for rows.Next() {
|
||||
game := model.Game{}
|
||||
cage := model.Cage{
|
||||
Game: game,
|
||||
}
|
||||
err := rows.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt, &game.ID)
|
||||
cage := model.Cage{}
|
||||
err := rows.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -34,19 +31,16 @@ func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error)
|
||||
return cages, nil
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) GetCageByID(gameID, cageID string) (*model.Cage, error) {
|
||||
func (db *DatabasePostgreSQL) GetCageByID(cageID string) (*model.Cage, error) {
|
||||
q := `
|
||||
SELECT c.id, created_at, updated_at, game_id
|
||||
SELECT c.id, created_at, updated_at
|
||||
FROM public.Cage c
|
||||
WHERE c.game_id=$1 and c.id = $2
|
||||
WHERE c.id = $2
|
||||
`
|
||||
row := db.session.QueryRow(q, gameID, cageID)
|
||||
row := db.session.QueryRow(q, cageID)
|
||||
|
||||
game := model.Game{}
|
||||
cage := model.Cage{
|
||||
Game: game,
|
||||
}
|
||||
err := row.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt, &game.ID)
|
||||
cage := model.Cage{}
|
||||
err := row.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt)
|
||||
if errPq, ok := err.(*pq.Error); ok {
|
||||
return nil, handlePgError(errPq)
|
||||
}
|
||||
@@ -57,21 +51,7 @@ func (db *DatabasePostgreSQL) GetCageByID(gameID, cageID string) (*model.Cage, e
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) CreateCage(cage *model.Cage) error {
|
||||
q := `
|
||||
INSERT INTO public.Cage
|
||||
(game_id)
|
||||
VALUES
|
||||
($1)
|
||||
RETURNING id, created_at
|
||||
`
|
||||
|
||||
err := db.session.
|
||||
QueryRow(q, cage.Game.ID).
|
||||
Scan(&cage.ID, &cage.CreatedAt)
|
||||
if errPq, ok := err.(*pq.Error); ok {
|
||||
return handlePgError(errPq)
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) DeleteCage(id string) error {
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/lib/pq"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
)
|
||||
|
||||
func (db *DatabasePostgreSQL) GetAllGames() ([]*model.Game, error) {
|
||||
q := `
|
||||
SELECT g.id, g.name, g.user_id, g.created_at, g.updated_at
|
||||
FROM public.game g
|
||||
`
|
||||
rows, err := db.session.Query(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
games := make([]*model.Game, 0)
|
||||
for rows.Next() {
|
||||
user := model.User{}
|
||||
game := model.Game{}
|
||||
err := rows.Scan(&game.ID, &game.Name, &user.ID, &game.CreatedAt, &game.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
games = append(games, &game)
|
||||
}
|
||||
return games, nil
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) GetGameByID(id string) (*model.Game, error) {
|
||||
q := `
|
||||
SELECT g.id, g.name, g.user_id, g.created_at, g.updated_at
|
||||
FROM public.game g
|
||||
WHERE g.id = $1
|
||||
`
|
||||
row := db.session.QueryRow(q, id)
|
||||
user := model.User{}
|
||||
game := model.Game{}
|
||||
err := row.Scan(&game.ID, &game.Name, &user.ID, &game.CreatedAt, &game.UpdatedAt)
|
||||
if errPq, ok := err.(*pq.Error); ok {
|
||||
return nil, handlePgError(errPq)
|
||||
}
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, dao.NewDAOError(dao.ErrTypeNotFound, err)
|
||||
}
|
||||
return &game, err
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) CreateGame(game *model.Game) error {
|
||||
q := `
|
||||
INSERT INTO public.game
|
||||
(user_id, name)
|
||||
VALUES
|
||||
($1, $2)
|
||||
RETURNING id, created_at
|
||||
`
|
||||
|
||||
err := db.session.
|
||||
QueryRow(q, game.User.ID, game.Name).
|
||||
Scan(&game.ID, &game.CreatedAt)
|
||||
if errPq, ok := err.(*pq.Error); ok {
|
||||
return handlePgError(errPq)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) DeleteGame(id string) error {
|
||||
q := `
|
||||
DELETE FROM public.game
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
_, err := db.session.Exec(q, id)
|
||||
if errPq, ok := err.(*pq.Error); ok {
|
||||
return handlePgError(errPq)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) GetHamstersOfGame(gameID string) ([]*model.Hamster, error) {
|
||||
q := `
|
||||
SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id
|
||||
FROM public.Hamster h
|
||||
JOIN public.cage c
|
||||
ON c.id = h.cage_id
|
||||
JOIN public.game g
|
||||
on c.game_id = g.id
|
||||
WHERE g.id = $1
|
||||
`
|
||||
rows, err := db.session.Query(q, gameID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
hamsters := make([]*model.Hamster, 0)
|
||||
for rows.Next() {
|
||||
hamster := model.Hamster{
|
||||
Mother: &model.Hamster{},
|
||||
Father: &model.Hamster{},
|
||||
GestationFather: &model.Hamster{},
|
||||
}
|
||||
err := rows.Scan(&hamster.ID, &hamster.CreatedAt,
|
||||
&hamster.UpdatedAt, &hamster.Name,
|
||||
&hamster.Number, &hamster.Sexe,
|
||||
&hamster.Age, &hamster.Father.ID,
|
||||
&hamster.Mother.ID, &hamster.HungerLevel,
|
||||
&hamster.ThirstLevel, &hamster.Weight,
|
||||
&hamster.Height, &hamster.Alive,
|
||||
&hamster.Sold, &hamster.Gestation,
|
||||
&hamster.GestationPeriod, &hamster.GestationCooldown,
|
||||
&hamster.GestationFather.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hamsters = append(hamsters, &hamster)
|
||||
}
|
||||
return hamsters, nil
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) UpdateGame(*model.Game) error {
|
||||
return nil
|
||||
}
|
||||
@@ -2,20 +2,20 @@ package postgresql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/lib/pq"
|
||||
"hamster-tycoon/storage/dao"
|
||||
"hamster-tycoon/storage/model"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Hamster, error) {
|
||||
func (db *DatabasePostgreSQL) GetAllHamsters(cageID string) ([]*model.Hamster, error) {
|
||||
q := `
|
||||
SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id
|
||||
SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id
|
||||
FROM hamster h
|
||||
JOIN cage c ON h.cage_id = c.id
|
||||
JOIN game g on c.game_id = g.id
|
||||
WHERE c.id=$1 and g.id=$2
|
||||
`
|
||||
rows, err := db.session.Query(q, cageID, gameID)
|
||||
rows, err := db.session.Query(q, cageID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -36,7 +36,7 @@ func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Ha
|
||||
&hamster.Mother.ID, &hamster.HungerLevel,
|
||||
&hamster.ThirstLevel, &hamster.Weight,
|
||||
&hamster.Height, &hamster.Alive,
|
||||
&hamster.Sold, &hamster.Gestation,
|
||||
&hamster.Sold, &hamster.Golden, &hamster.Gestation,
|
||||
&hamster.GestationPeriod, &hamster.GestationCooldown,
|
||||
&hamster.GestationFather.ID, &hamster.Cage.ID)
|
||||
if err != nil {
|
||||
@@ -47,15 +47,14 @@ func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Ha
|
||||
return hamsters, nil
|
||||
}
|
||||
|
||||
func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model.Hamster, error) {
|
||||
func (db *DatabasePostgreSQL) GetHamsterByID(id, cageID string) (*model.Hamster, error) {
|
||||
q := `
|
||||
SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id
|
||||
SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id
|
||||
FROM hamster h
|
||||
JOIN cage c ON h.cage_id = c.id
|
||||
JOIN game g on c.game_id = g.id
|
||||
WHERE h.id=$1 and c.id=$2 and g.id=$3
|
||||
`
|
||||
row := db.session.QueryRow(q, id, cageID, gameID)
|
||||
row := db.session.QueryRow(q, id, cageID)
|
||||
|
||||
hamster := model.Hamster{
|
||||
Mother: &model.Hamster{},
|
||||
@@ -70,7 +69,7 @@ func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model.
|
||||
&hamster.Mother.ID, &hamster.HungerLevel,
|
||||
&hamster.ThirstLevel, &hamster.Weight,
|
||||
&hamster.Height, &hamster.Alive,
|
||||
&hamster.Sold, &hamster.Gestation,
|
||||
&hamster.Sold, &hamster.Golden, &hamster.Gestation,
|
||||
&hamster.GestationPeriod, &hamster.GestationCooldown,
|
||||
&hamster.GestationFather.ID, &hamster.Cage.ID)
|
||||
|
||||
@@ -86,7 +85,7 @@ func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model.
|
||||
func (db *DatabasePostgreSQL) CreateHamster(hamster *model.Hamster) error {
|
||||
q := `
|
||||
INSERT INTO public.Hamster
|
||||
(name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id,cage_id)
|
||||
(name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id,cage_id)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
RETURNING id, created_at
|
||||
@@ -99,7 +98,7 @@ func (db *DatabasePostgreSQL) CreateHamster(hamster *model.Hamster) error {
|
||||
&hamster.Mother.ID, &hamster.HungerLevel,
|
||||
&hamster.ThirstLevel, &hamster.Weight,
|
||||
&hamster.Height, &hamster.Alive,
|
||||
&hamster.Sold, &hamster.Gestation,
|
||||
&hamster.Sold, &hamster.Golden, &hamster.Gestation,
|
||||
&hamster.GestationPeriod, &hamster.GestationCooldown,
|
||||
&hamster.GestationFather.ID, &hamster.Cage.ID).
|
||||
Scan(&hamster.ID, &hamster.CreatedAt)
|
||||
|
||||
@@ -4,7 +4,6 @@ import "time"
|
||||
|
||||
type Cage struct {
|
||||
ID string `json:"id"`
|
||||
Game Game `json:"game"`
|
||||
Hamsters []*Hamster `json:"hamsters"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt"`
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Game struct {
|
||||
ID string `json:"game_id"`
|
||||
User User `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Cages []*Cage `json:"cages"`
|
||||
SoldHamster []*Hamster `json:"sold_hamsters"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt"`
|
||||
}
|
||||
@@ -10,7 +10,6 @@ type User struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt"`
|
||||
GoogleID string `json:"-"`
|
||||
Games []Game
|
||||
}
|
||||
|
||||
type UserEditable struct {
|
||||
|
||||
Reference in New Issue
Block a user