mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
210 lines
4.9 KiB
Go
210 lines
4.9 KiB
Go
package redis
|
|
|
|
import (
|
|
stdContext "context"
|
|
"io"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
)
|
|
|
|
type (
|
|
// Options is just a type alias for the go-redis Client Options.
|
|
Options = redis.Options
|
|
// ClusterOptions is just a type alias for the go-redis Cluster Client Options.
|
|
ClusterOptions = redis.ClusterOptions
|
|
)
|
|
|
|
// GoRedisClient is the interface which both
|
|
// go-redis' Client and Cluster Client implements.
|
|
type GoRedisClient interface {
|
|
redis.Cmdable // Commands.
|
|
io.Closer // CloseConnection.
|
|
}
|
|
|
|
// GoRedisDriver implements the Sessions Database Driver
|
|
// for the go-redis redis driver. See driver.go file.
|
|
type GoRedisDriver struct {
|
|
// Both Client and ClusterClient implements this interface.
|
|
// Custom one can be directly passed but if so, the
|
|
// Connect method does nothing (so all connection and client settings are ignored).
|
|
Client GoRedisClient
|
|
// Customize any go-redis fields manually
|
|
// before Connect.
|
|
ClientOptions Options
|
|
ClusterOptions ClusterOptions
|
|
}
|
|
|
|
var defaultContext = stdContext.Background()
|
|
|
|
func (r *GoRedisDriver) mergeClientOptions(c Config) *Options {
|
|
opts := r.ClientOptions
|
|
if opts.Addr == "" {
|
|
opts.Addr = c.Addr
|
|
}
|
|
|
|
if opts.Username == "" {
|
|
opts.Username = c.Username
|
|
}
|
|
|
|
if opts.Password == "" {
|
|
opts.Password = c.Password
|
|
}
|
|
|
|
if opts.DB == 0 {
|
|
opts.DB, _ = strconv.Atoi(c.Database)
|
|
}
|
|
|
|
if opts.ReadTimeout == 0 {
|
|
opts.ReadTimeout = c.Timeout
|
|
}
|
|
|
|
if opts.WriteTimeout == 0 {
|
|
opts.WriteTimeout = c.Timeout
|
|
}
|
|
|
|
if opts.Network == "" {
|
|
opts.Network = c.Network
|
|
}
|
|
|
|
if opts.TLSConfig == nil {
|
|
opts.TLSConfig = c.TLSConfig
|
|
}
|
|
|
|
if opts.PoolSize == 0 {
|
|
opts.PoolSize = c.MaxActive
|
|
}
|
|
|
|
return &opts
|
|
}
|
|
|
|
func (r *GoRedisDriver) mergeClusterOptions(c Config) *ClusterOptions {
|
|
opts := r.ClusterOptions
|
|
|
|
if opts.Username == "" {
|
|
opts.Username = c.Username
|
|
}
|
|
|
|
if opts.Password == "" {
|
|
opts.Password = c.Password
|
|
}
|
|
|
|
if opts.ReadTimeout == 0 {
|
|
opts.ReadTimeout = c.Timeout
|
|
}
|
|
|
|
if opts.WriteTimeout == 0 {
|
|
opts.WriteTimeout = c.Timeout
|
|
}
|
|
|
|
if opts.TLSConfig == nil {
|
|
opts.TLSConfig = c.TLSConfig
|
|
}
|
|
|
|
if opts.PoolSize == 0 {
|
|
opts.PoolSize = c.MaxActive
|
|
}
|
|
|
|
if len(opts.Addrs) == 0 {
|
|
opts.Addrs = c.Clusters
|
|
}
|
|
|
|
return &opts
|
|
}
|
|
|
|
// SetClient sets an existing go redis client to the sessions redis driver.
|
|
//
|
|
// Returns itself.
|
|
func (r *GoRedisDriver) SetClient(goRedisClient GoRedisClient) *GoRedisDriver {
|
|
r.Client = goRedisClient
|
|
return r
|
|
}
|
|
|
|
// Connect initializes the redis client.
|
|
func (r *GoRedisDriver) Connect(c Config) error {
|
|
if r.Client != nil { // if a custom one was given through SetClient.
|
|
return nil
|
|
}
|
|
|
|
if len(c.Clusters) > 0 {
|
|
r.Client = redis.NewClusterClient(r.mergeClusterOptions(c))
|
|
} else {
|
|
r.Client = redis.NewClient(r.mergeClientOptions(c))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// PingPong sends a ping message and reports whether
|
|
// the PONG message received successfully.
|
|
func (r *GoRedisDriver) PingPong() (bool, error) {
|
|
pong, err := r.Client.Ping(defaultContext).Result()
|
|
return pong == "PONG", err
|
|
}
|
|
|
|
// CloseConnection terminates the underline redis connection.
|
|
func (r *GoRedisDriver) CloseConnection() error {
|
|
return r.Client.Close()
|
|
}
|
|
|
|
// Set stores a "value" based on the session's "key".
|
|
// The value should be type of []byte, so unmarshal can happen.
|
|
func (r *GoRedisDriver) Set(sid, key string, value interface{}) error {
|
|
return r.Client.HSet(defaultContext, sid, key, value).Err()
|
|
}
|
|
|
|
// Get returns the associated value of the session's given "key".
|
|
func (r *GoRedisDriver) Get(sid, key string) (interface{}, error) {
|
|
return r.Client.HGet(defaultContext, sid, key).Bytes()
|
|
}
|
|
|
|
// Exists reports whether a session exists or not.
|
|
func (r *GoRedisDriver) Exists(sid string) bool {
|
|
n, err := r.Client.Exists(defaultContext, sid).Result()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return n > 0
|
|
}
|
|
|
|
// TTL returns any TTL value of the session.
|
|
func (r *GoRedisDriver) TTL(sid string) time.Duration {
|
|
dur, err := r.Client.TTL(defaultContext, sid).Result()
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
return dur
|
|
}
|
|
|
|
// UpdateTTL sets expiration duration of the session.
|
|
func (r *GoRedisDriver) UpdateTTL(sid string, newLifetime time.Duration) error {
|
|
_, err := r.Client.Expire(defaultContext, sid, newLifetime).Result()
|
|
return err
|
|
}
|
|
|
|
// GetAll returns all the key values under the session.
|
|
func (r *GoRedisDriver) GetAll(sid string) (map[string]string, error) {
|
|
return r.Client.HGetAll(defaultContext, sid).Result()
|
|
}
|
|
|
|
// GetKeys returns all keys under the session.
|
|
func (r *GoRedisDriver) GetKeys(sid string) ([]string, error) {
|
|
return r.Client.HKeys(defaultContext, sid).Result()
|
|
}
|
|
|
|
// Len returns the total length of key-values of the session.
|
|
func (r *GoRedisDriver) Len(sid string) int {
|
|
return int(r.Client.HLen(defaultContext, sid).Val())
|
|
}
|
|
|
|
// Delete removes a value from the redis store.
|
|
func (r *GoRedisDriver) Delete(sid, key string) error {
|
|
if key == "" {
|
|
return r.Client.Del(defaultContext, sid).Err()
|
|
}
|
|
return r.Client.HDel(defaultContext, sid, key).Err()
|
|
}
|