117 lines
2.5 KiB
Go
117 lines
2.5 KiB
Go
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
|
|
}
|