Files
mineatar-api-server/src/redis.go
2023-05-02 20:57:56 -05:00

162 lines
3.5 KiB
Go

package main
import (
"bytes"
"context"
"fmt"
"image"
"image/draw"
"time"
"github.com/go-redis/redis/v8"
)
// Redis is a utility client for reading and writing values to the Redis server.
type Redis struct {
conn *redis.Client
}
// Connect connects to the Redis server using the configuration values provided.
func (r *Redis) Connect(conf RedisConfig) error {
c := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", conf.Host, conf.Port),
Username: conf.User,
Password: conf.Password,
DB: conf.Database,
})
r.conn = c
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
return c.Ping(ctx).Err()
}
// Scan returns all keys by the pattern in the Redis database.
func (r *Redis) Scan(cursor uint64, pattern string, count int64) ([]string, uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
res := r.conn.Scan(ctx, cursor, pattern, count)
if err := res.Err(); err != nil {
return nil, 0, err
}
return res.Result()
}
// GetString gets the value from Redis by the key and returns the value as a string.
func (r *Redis) GetString(key string) (string, bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
existsResult := r.conn.Exists(ctx, key)
if err := existsResult.Err(); err != nil {
return "", false, err
}
if existsResult.Val() == 0 {
return "", false, nil
}
result := r.conn.Get(ctx, key)
return result.Val(), true, result.Err()
}
// GetBytes gets the value from Redis by the key and returns the value as a byte array.
func (r *Redis) GetBytes(key string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
existsResult := r.conn.Exists(ctx, key)
if err := existsResult.Err(); err != nil {
return nil, err
}
if existsResult.Val() == 0 {
return nil, nil
}
result := r.conn.Get(ctx, key)
if err := result.Err(); err != nil {
return nil, err
}
data, err := result.Bytes()
return data, err
}
// GetNRGBA gets the value from Redis by the key and returns the value as Go image.NRGBA image type.
func (r *Redis) GetNRGBA(key string) (*image.NRGBA, bool, error) {
value, err := r.GetBytes(key)
if err != nil {
return nil, false, err
}
if value == nil {
return nil, false, nil
}
img, format, err := image.Decode(bytes.NewReader(value))
if err != nil {
return nil, false, err
}
if format != "NRGBA" {
outputImg := image.NewNRGBA(img.Bounds())
draw.Draw(outputImg, img.Bounds(), img, image.Pt(0, 0), draw.Src)
return outputImg, true, nil
}
return img.(*image.NRGBA), true, nil
}
// Exists returns whether or not the key exists in the database.
func (r *Redis) Exists(key string) (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
result := r.conn.Exists(ctx, key)
return result.Val() == 1, result.Err()
}
// Delete deletes the key from the database if it exists.
func (r *Redis) Delete(key string) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
return r.conn.Del(ctx, key).Err()
}
// Set puts the key-value into the database with an optional TTL value.
func (r *Redis) Set(key string, value interface{}, ttl time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
return r.conn.Set(ctx, key, value, ttl).Err()
}
// Close closes the connection to the database.
func (r *Redis) Close() error {
return r.conn.Close()
}