This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
heroagent_go_old/pkg2_dont_use/heroagent/api/redisserver.go
2025-05-23 15:40:41 +04:00

450 lines
11 KiB
Go

package api
import (
"context"
"time"
"github.com/gofiber/fiber/v2"
"github.com/redis/go-redis/v9"
)
// RedisHandler handles Redis-related API endpoints
type RedisHandler struct {
redisClient *redis.Client
}
// NewRedisHandler creates a new Redis handler
func NewRedisHandler(redisAddr string, isUnixSocket bool) *RedisHandler {
// Determine network type
networkType := "tcp"
if isUnixSocket {
networkType = "unix"
}
// Create Redis client
client := redis.NewClient(&redis.Options{
Network: networkType,
Addr: redisAddr,
DB: 0,
DialTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
})
return &RedisHandler{
redisClient: client,
}
}
// RegisterRoutes registers Redis routes to the fiber app
func (h *RedisHandler) RegisterRoutes(app *fiber.App) {
group := app.Group("/api/redis")
// @Summary Set a Redis key
// @Description Set a key-value pair in Redis with optional expiration
// @Tags redis
// @Accept json
// @Produce json
// @Param request body SetKeyRequest true "Key-value data"
// @Success 200 {object} SetKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/set [post]
group.Post("/set", h.setKey)
// @Summary Get a Redis key
// @Description Get a value by key from Redis
// @Tags redis
// @Produce json
// @Param key path string true "Key to retrieve"
// @Success 200 {object} GetKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 404 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/get/{key} [get]
group.Get("/get/:key", h.getKey)
// @Summary Delete a Redis key
// @Description Delete a key from Redis
// @Tags redis
// @Produce json
// @Param key path string true "Key to delete"
// @Success 200 {object} DeleteKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/del/{key} [delete]
group.Delete("/del/:key", h.deleteKey)
// @Summary Get Redis keys by pattern
// @Description Get keys matching a pattern from Redis
// @Tags redis
// @Produce json
// @Param pattern path string true "Pattern to match keys"
// @Success 200 {object} GetKeysResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/keys/{pattern} [get]
group.Get("/keys/:pattern", h.getKeys)
// @Summary Set hash fields
// @Description Set one or more fields in a Redis hash
// @Tags redis
// @Accept json
// @Produce json
// @Param request body HSetKeyRequest true "Hash field data"
// @Success 200 {object} HSetKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/hset [post]
group.Post("/hset", h.hsetKey)
// @Summary Get hash field
// @Description Get a field from a Redis hash
// @Tags redis
// @Produce json
// @Param key path string true "Hash key"
// @Param field path string true "Field to retrieve"
// @Success 200 {object} HGetKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 404 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/hget/{key}/{field} [get]
group.Get("/hget/:key/:field", h.hgetKey)
// @Summary Delete hash fields
// @Description Delete one or more fields from a Redis hash
// @Tags redis
// @Accept json
// @Produce json
// @Param request body HDelKeyRequest true "Fields to delete"
// @Success 200 {object} HDelKeyResponse
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/hdel [post]
group.Post("/hdel", h.hdelKey)
// @Summary Get hash fields
// @Description Get all field names in a Redis hash
// @Tags redis
// @Produce json
// @Param key path string true "Hash key"
// @Success 200 {object} HKeysResponse
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/hkeys/{key} [get]
group.Get("/hkeys/:key", h.hkeysKey)
// @Summary Get all hash fields and values
// @Description Get all fields and values in a Redis hash
// @Tags redis
// @Produce json
// @Param key path string true "Hash key"
// @Success 200 {object} map[string]string
// @Failure 400 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/redis/hgetall/{key} [get]
group.Get("/hgetall/:key", h.hgetallKey)
}
// setKey sets a key-value pair in Redis
func (h *RedisHandler) setKey(c *fiber.Ctx) error {
// Parse request
var req struct {
Key string `json:"key"`
Value string `json:"value"`
Expires int `json:"expires,omitempty"` // Expiration in seconds, optional
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Invalid request format: " + err.Error(),
})
}
// Validate required fields
if req.Key == "" || req.Value == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key and value are required",
})
}
ctx := context.Background()
var err error
// Set with or without expiration
if req.Expires > 0 {
err = h.redisClient.Set(ctx, req.Key, req.Value, time.Duration(req.Expires)*time.Second).Err()
} else {
err = h.redisClient.Set(ctx, req.Key, req.Value, 0).Err()
}
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to set key: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"message": "Key set successfully",
})
}
// getKey retrieves a value by key from Redis
func (h *RedisHandler) getKey(c *fiber.Ctx) error {
key := c.Params("key")
if key == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key is required",
})
}
ctx := context.Background()
val, err := h.redisClient.Get(ctx, key).Result()
if err == redis.Nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
"success": false,
"error": "Key not found",
})
} else if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to get key: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"key": key,
"value": val,
})
}
// deleteKey deletes a key from Redis
func (h *RedisHandler) deleteKey(c *fiber.Ctx) error {
key := c.Params("key")
if key == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key is required",
})
}
ctx := context.Background()
result, err := h.redisClient.Del(ctx, key).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to delete key: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"deleted": result > 0,
"count": result,
})
}
// getKeys retrieves keys matching a pattern from Redis
func (h *RedisHandler) getKeys(c *fiber.Ctx) error {
pattern := c.Params("pattern", "*")
ctx := context.Background()
keys, err := h.redisClient.Keys(ctx, pattern).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to get keys: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"keys": keys,
"count": len(keys),
})
}
// hsetKey sets a field in a hash stored at key
func (h *RedisHandler) hsetKey(c *fiber.Ctx) error {
// Parse request
var req struct {
Key string `json:"key"`
Fields map[string]string `json:"fields"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Invalid request format: " + err.Error(),
})
}
// Validate required fields
if req.Key == "" || len(req.Fields) == 0 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key and at least one field are required",
})
}
ctx := context.Background()
totalAdded := 0
// Use HSet to set multiple fields at once
for field, value := range req.Fields {
added, err := h.redisClient.HSet(ctx, req.Key, field, value).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to set hash field: " + err.Error(),
})
}
totalAdded += int(added)
}
return c.JSON(fiber.Map{
"success": true,
"added": totalAdded,
})
}
// hgetKey retrieves a field from a hash stored at key
func (h *RedisHandler) hgetKey(c *fiber.Ctx) error {
key := c.Params("key")
field := c.Params("field")
if key == "" || field == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key and field are required",
})
}
ctx := context.Background()
val, err := h.redisClient.HGet(ctx, key, field).Result()
if err == redis.Nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
"success": false,
"error": "Field not found in hash",
})
} else if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to get hash field: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"key": key,
"field": field,
"value": val,
})
}
// hdelKey deletes fields from a hash stored at key
func (h *RedisHandler) hdelKey(c *fiber.Ctx) error {
// Parse request
var req struct {
Key string `json:"key"`
Fields []string `json:"fields"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Invalid request format: " + err.Error(),
})
}
// Validate required fields
if req.Key == "" || len(req.Fields) == 0 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key and at least one field are required",
})
}
ctx := context.Background()
fields := make([]string, len(req.Fields))
copy(fields, req.Fields)
removed, err := h.redisClient.HDel(ctx, req.Key, fields...).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to delete hash fields: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"removed": removed,
})
}
// hkeysKey retrieves all field names in a hash stored at key
func (h *RedisHandler) hkeysKey(c *fiber.Ctx) error {
key := c.Params("key")
if key == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key is required",
})
}
ctx := context.Background()
fields, err := h.redisClient.HKeys(ctx, key).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to get hash keys: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"key": key,
"fields": fields,
"count": len(fields),
})
}
// hgetallKey retrieves all fields and values in a hash stored at key
func (h *RedisHandler) hgetallKey(c *fiber.Ctx) error {
key := c.Params("key")
if key == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"error": "Key is required",
})
}
ctx := context.Background()
values, err := h.redisClient.HGetAll(ctx, key).Result()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"error": "Failed to get hash: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"success": true,
"key": key,
"hash": values,
"count": len(values),
})
}