package redis import ( "context" "fmt" "time" "github.com/alicebob/miniredis/v2" "github.com/redis/go-redis/v9" "carrot_bbs/internal/config" ) // Client Redis客户端 type Client struct { rdb *redis.Client isMiniRedis bool mr *miniredis.Miniredis } // New 创建Redis客户端 func New(cfg *config.RedisConfig) (*Client, error) { switch cfg.Type { case "miniredis": // 启动内嵌Redis模拟 mr, err := miniredis.Run() if err != nil { return nil, fmt.Errorf("failed to start miniredis: %w", err) } rdb := redis.NewClient(&redis.Options{ Addr: mr.Addr(), Password: "", DB: 0, }) return &Client{ rdb: rdb, isMiniRedis: true, mr: mr, }, nil case "redis": // 使用真实Redis rdb := redis.NewClient(&redis.Options{ Addr: cfg.Redis.Addr(), Password: cfg.Redis.Password, DB: cfg.Redis.DB, PoolSize: cfg.PoolSize, }) ctx := context.Background() if err := rdb.Ping(ctx).Err(); err != nil { return nil, fmt.Errorf("failed to connect to redis: %w", err) } return &Client{rdb: rdb, isMiniRedis: false}, nil default: // 默认使用miniredis mr, err := miniredis.Run() if err != nil { return nil, fmt.Errorf("failed to start miniredis: %w", err) } rdb := redis.NewClient(&redis.Options{ Addr: mr.Addr(), }) return &Client{ rdb: rdb, isMiniRedis: true, mr: mr, }, nil } } // Get 获取值 func (c *Client) Get(ctx context.Context, key string) (string, error) { return c.rdb.Get(ctx, key).Result() } // Set 设置值 func (c *Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error { return c.rdb.Set(ctx, key, value, expiration).Err() } // Del 删除键 func (c *Client) Del(ctx context.Context, keys ...string) error { return c.rdb.Del(ctx, keys...).Err() } // Exists 检查键是否存在 func (c *Client) Exists(ctx context.Context, keys ...string) (int64, error) { return c.rdb.Exists(ctx, keys...).Result() } // Incr 递增 func (c *Client) Incr(ctx context.Context, key string) (int64, error) { return c.rdb.Incr(ctx, key).Result() } // Expire 设置过期时间 func (c *Client) Expire(ctx context.Context, key string, expiration time.Duration) (bool, error) { return c.rdb.Expire(ctx, key, expiration).Result() } // GetClient 获取原生客户端 func (c *Client) GetClient() *redis.Client { return c.rdb } // Close 关闭连接 func (c *Client) Close() error { if err := c.rdb.Close(); err != nil { return err } if c.mr != nil { c.mr.Close() } return nil } // IsMiniRedis 返回是否是miniredis func (c *Client) IsMiniRedis() bool { return c.isMiniRedis }