Files
InfantrySkillCalculator/controllers/cache_controller.go

132 lines
3.5 KiB
Go

package controllers
import (
"InfantrySkillCalculator/models"
"InfantrySkillCalculator/utils"
"context"
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"net/http"
"time"
)
type AddCacheInput struct {
PlayerID uint `json:"player_id" binding:"required"`
CacheDate time.Time `json:"date" binding:"required"`
Score float32 `json:"score" gorm:"default:-1.0"`
Game string `json:"game" binding:"required"`
}
type UpdateCacheInput struct {
CacheDate time.Time `json:"date" binding:"required"`
Score float32 `json:"score" gorm:"default:-1.0"`
}
var ctx = context.Background()
// GetCacheByPlayerID GET /cache/:player_id?game_id=TAG
func GetCacheByPlayerID(c *gin.Context) {
playerId := utils.StringToUint(c.Param("player_id"))
gameId := utils.StringToUint(c.Request.URL.Query().Get("game_id"))
val, err := GetCacheByPlayerIDGorm(playerId, gameId)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
} else {
c.JSON(http.StatusOK, val)
}
}
func GetCacheByPlayerIDGorm(playerId uint, gameId uint) (float32, error) {
key := fmt.Sprintf("player:%d:game:%d", playerId, gameId)
val, err := models.Cache.Get(ctx, key).Result()
if errors.Is(err, redis.Nil) {
return -1.0, nil // cache miss
} else if err != nil {
return -1.0, err // cache error
} else {
return utils.StringToFloat(val), nil // cache hit
}
}
// AddCache POST /cache
func AddCache(c *gin.Context) {
var input AddCacheInput
if err := c.BindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var game models.Game
if err := FindGameByTag(&game, input.Game).Error; err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Game not found!"})
return
}
cache := models.PlayerCache{CacheDate: input.CacheDate, PlayerID: input.PlayerID, Score: input.Score, Game: input.Game}
c.JSON(http.StatusOK, cache)
}
// UpdateCacheByPlayerID PATCH /cache/:id?game=TAG
func UpdateCacheByPlayerID(c *gin.Context) {
var cache models.PlayerCache
if err := FindCacheGin(&cache, c).Error; err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
return
}
var input UpdateCacheInput
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
models.DB.Model(&cache).Updates(map[string]interface{}{
"CacheDate": input.CacheDate,
"Score": input.Score,
})
c.JSON(http.StatusOK, cache)
}
// DeleteCacheByPlayerID DELETE /cache/:id?game=TAG
func DeleteCacheByPlayerID(c *gin.Context) {
var cache models.PlayerCache
if err := FindCacheGin(&cache, c).Error; err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
return
}
models.DB.Delete(&cache)
c.JSON(http.StatusOK, true)
}
// DeleteAllCaches DELETE /cache
func DeleteAllCaches(c *gin.Context) {
var caches []models.PlayerCache
if err := models.DB.
Session(&gorm.Session{AllowGlobalUpdate: true}).
Clauses(clause.Returning{}).
Delete(&caches).Error; err != nil {
c.String(http.StatusBadRequest, "Purge failed! Error: "+err.Error())
return
}
c.String(http.StatusOK, "Purged "+utils.UintToString(uint(len(caches)))+" caches!")
}
func FindCacheGin(out interface{}, c *gin.Context) *gorm.DB {
return FindCache(out, utils.StringToUint(c.Param("id")), c.Request.URL.Query().Get("game"))
}
func FindCache(out interface{}, id uint, game string) *gorm.DB {
return models.DB.Where("player_id = ?", id).Where("game = ?", game).First(out)
}