You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
1.6 KiB

package cache
import (
"errors"
"github.com/vmihailenco/msgpack/v4"
"net/url"
"strconv"
"strings"
"time"
)
const (
Memcache = "memcache"
Redis = "redis"
Memory = "memory"
)
var (
ErrInvalidDriver = errors.New("invalid driver")
)
type CacheInterface interface {
Has(key string) bool
Get(key string, dst ...interface{}) ([]byte, error)
Set(key string, val interface{}, ttl time.Duration) (err error)
Del(key string) error
}
func New(uri string) (CacheInterface, error) {
u, err := url.Parse(uri)
if err != nil {
return nil, err
}
query := u.Query()
switch u.Scheme {
case Redis:
return NewRedisCache(RedisSettings{
Address: u.Host,
Password: query.Get("password"),
})
case Memcache:
return NewMemcacheCache(MemcacheSettings{
Servers: strings.Split(u.Host, ","),
})
case Memory:
cleanupTime := query.Get("cleanupTime")
if cleanupTime == "" {
cleanupTime = "30"
}
i, err := strconv.Atoi(cleanupTime)
if err != nil {
return nil, err
}
return NewMemoryCache(time.Duration(i) * time.Second)
}
return nil, ErrInvalidDriver
}
func encodeValue(val interface{}) ([]byte, error) {
var v []byte
if b, ok := val.([]byte); ok {
v = b
} else if s, ok := val.(string); ok {
b = []byte(s)
} else {
b, err := msgpack.Marshal(val)
if err != nil {
return nil, err
}
v = b
}
return v, nil
}
func decodeDst(b []byte, v interface{}) ([]byte, error) {
switch v := v.(type) {
case *[]byte:
if v != nil {
*v = b
return b, nil
}
case *string:
if v != nil {
*v = string(b)
return b, nil
}
}
err := msgpack.Unmarshal(b, v)
if err != nil {
return nil, err
}
return b, nil
}