mirror of
https://github.com/parkan/go-hauk.git
synced 2026-05-08 16:47:46 +02:00
105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type Store interface {
|
|
Get(ctx context.Context, key string, v any) error
|
|
Set(ctx context.Context, key string, v any, expireAt time.Time) error
|
|
SetTTL(ctx context.Context, key string, v any, ttl time.Duration) error
|
|
Delete(ctx context.Context, key string) error
|
|
Exists(ctx context.Context, key string) (bool, error)
|
|
}
|
|
|
|
type Redis struct {
|
|
client *redis.Client
|
|
prefix string
|
|
}
|
|
|
|
func NewRedis(addr, password, prefix string) (*Redis, error) {
|
|
var opts *redis.Options
|
|
var err error
|
|
|
|
// redis:// URL detection
|
|
if strings.HasPrefix(addr, "redis://") || strings.HasPrefix(addr, "rediss://") {
|
|
opts, err = redis.ParseURL(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else if strings.HasPrefix(addr, "/") {
|
|
// unix socket
|
|
opts = &redis.Options{
|
|
Network: "unix",
|
|
Addr: addr,
|
|
Password: password,
|
|
}
|
|
} else {
|
|
// host:port
|
|
opts = &redis.Options{
|
|
Addr: addr,
|
|
Password: password,
|
|
}
|
|
}
|
|
|
|
client := redis.NewClient(opts)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
if err := client.Ping(ctx).Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Redis{
|
|
client: client,
|
|
prefix: prefix,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Redis) key(k string) string {
|
|
return r.prefix + "-" + k
|
|
}
|
|
|
|
func (r *Redis) Get(ctx context.Context, key string, v any) error {
|
|
data, err := r.client.Get(ctx, r.key(key)).Bytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(data, v)
|
|
}
|
|
|
|
func (r *Redis) Set(ctx context.Context, key string, v any, expireAt time.Time) error {
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.client.Set(ctx, r.key(key), data, time.Until(expireAt)).Err()
|
|
}
|
|
|
|
func (r *Redis) SetTTL(ctx context.Context, key string, v any, ttl time.Duration) error {
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.client.Set(ctx, r.key(key), data, ttl).Err()
|
|
}
|
|
|
|
func (r *Redis) Delete(ctx context.Context, key string) error {
|
|
return r.client.Del(ctx, r.key(key)).Err()
|
|
}
|
|
|
|
func (r *Redis) Exists(ctx context.Context, key string) (bool, error) {
|
|
n, err := r.client.Exists(ctx, r.key(key)).Result()
|
|
return n > 0, err
|
|
}
|
|
|
|
func (r *Redis) Close() error {
|
|
return r.client.Close()
|
|
}
|