package store import ( "context" "encoding/json" "time" "astraltech.xyz/accountmanager/src/logging" "github.com/redis/go-redis/v9" ) type RedisStore[Value any] struct { client *redis.Client ctx context.Context prefix string } func (m *RedisStore[Value]) RedisHash(value_to_hash string) string { return m.prefix + HashKey(value_to_hash) } func NewRedisStore[Value any]() *RedisStore[Value] { logging.Debug("Creating new redis session store") // this will be replaced with a URL that can be parsed in the config file redis_server := "redis://localhost:6379/0" opts, err := redis.ParseURL(redis_server) if err != nil { logging.Errorf("Failed to parse redis url %s", err.Error()) } rdb := redis.NewClient(opts) ctx := context.Background() if err := rdb.Ping(ctx).Err(); err != nil { logging.Errorf("Failed to connect to redis server %s", redis_server) } else { logging.Infof("Successfully connected to redis server %s", redis_server) } store := &RedisStore[Value]{ client: rdb, ctx: ctx, } return store } func (m *RedisStore[Value]) Create(key string, value Value) (err error) { hashedSession := m.RedisHash(key) data, err := json.Marshal(value) if err != nil { return ErrKeyBackend } created, err := m.client.SetNX(m.ctx, hashedSession, data, time.Hour).Result() if err != nil { logging.Error(err.Error()) return ErrKeyBackend } if !created { return ErrKeyAlreadyExists } return nil } func (m *RedisStore[Value]) Get(sessionID string) (Value, error) { hashed := m.RedisHash(sessionID) var session_data Value data, err := m.client.Get(m.ctx, hashed).Bytes() if err == redis.Nil { return session_data, ErrKeyNotFound } else if err != nil { logging.Error(err.Error()) return session_data, ErrKeyBackend } if err := json.Unmarshal(data, session_data); err != nil { logging.Error(err.Error()) return session_data, ErrKeyBackend } return session_data, nil } func (m *RedisStore[Value]) Update(key string, value Value) error { hashedSession := m.RedisHash(key) data, err := json.Marshal(value) if err != nil { return ErrKeyBackend } updated, err := m.client.SetXX(m.ctx, hashedSession, data, time.Hour).Result() if err != nil { logging.Error(err.Error()) return ErrKeyBackend } if !updated { return ErrKeyNotFound } return nil } func (m *RedisStore[Value]) Delete(sessionID string) error { hashedSession := m.RedisHash(sessionID) err := m.client.Del(m.ctx, hashedSession).Err() if err != nil { logging.Error(err.Error()) return ErrKeyBackend } return nil }