162 lines
3.5 KiB
Go
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()
|
|
}
|