add more manage methods. modify some cache logic

This commit is contained in:
inhere
2021-06-30 01:24:32 +08:00
parent e7800134ac
commit 1af54fad12
21 changed files with 343 additions and 115 deletions

View File

@@ -5,12 +5,10 @@ import (
"time" "time"
"github.com/dgraph-io/badger" "github.com/dgraph-io/badger"
"github.com/gookit/cache"
) )
// BadgerDB definition // BadgerDB definition
type BadgerDB struct { type BadgerDB struct {
cache.BaseDriver
db *badger.DB db *badger.DB
} }

View File

@@ -43,7 +43,7 @@ func (c *BoltDB) Get(key string) interface{} {
b := tx.Bucket([]byte(c.Bucket)) b := tx.Bucket([]byte(c.Bucket))
bs := b.Get([]byte(key)) bs := b.Get([]byte(key))
if err := c.MustUnmarshal(bs, &val); err != nil { if err := c.UnmarshalTo(bs, &val); err != nil {
return err return err
} }
@@ -53,7 +53,6 @@ func (c *BoltDB) Get(key string) interface{} {
if err != nil { if err != nil {
return nil return nil
} }
return val return val
} }

View File

@@ -72,7 +72,7 @@ func (c *BuntDB) Get(key string) interface{} {
return err return err
} }
return c.MustUnmarshal([]byte(str), &val) return c.UnmarshalTo([]byte(str), &val)
}) })
if err != nil { if err != nil {
@@ -119,7 +119,7 @@ func (c *BuntDB) GetMulti(keys []string) map[string]interface{} {
} }
var val interface{} var val interface{}
err = c.MustUnmarshal([]byte(str), &val) err = c.UnmarshalTo([]byte(str), &val)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -83,11 +83,20 @@ var std = NewManager()
// Register driver to manager instance // Register driver to manager instance
func Register(name string, driver Cache) *Manager { func Register(name string, driver Cache) *Manager {
std.DefaultUse(name)
std.Register(name, driver) std.Register(name, driver)
return std return std
} }
// Unregister an cache driver
func Unregister(name string) {
std.Unregister(name)
}
// UnregisterAll cache drivers
func UnregisterAll(fn ...func(cache Cache)) {
std.UnregisterAll(fn...)
}
// SetDefName set default driver name. // SetDefName set default driver name.
// Deprecated // Deprecated
// please use DefaultUse() instead it // please use DefaultUse() instead it

View File

@@ -90,8 +90,8 @@ func (l *BaseDriver) Marshal(val interface{}) (interface{}, error) {
return val, nil return val, nil
} }
// MustUnmarshal cache value // UnmarshalTo cache value
func (l *BaseDriver) MustUnmarshal(bts []byte, ptr interface{}) error { func (l *BaseDriver) UnmarshalTo(bts []byte, ptr interface{}) error {
if Unmarshal == nil { if Unmarshal == nil {
return errNoUnmarshal return errNoUnmarshal
} }
@@ -115,16 +115,6 @@ func (l *BaseDriver) Unmarshal(val []byte, err error) interface{} {
return val return val
} }
// GetAs get cache value and decode value to object ptr
func (l *BaseDriver) GetAs(key string, ptr interface{}) error {
// TODO bts, err := c.Get(key)
// if Unmarshal != nil {
// err := Unmarshal(bts, ptr)
// return err
// }
panic("please implement me")
}
// Key real cache key build // Key real cache key build
func (l *BaseDriver) Key(key string) string { func (l *BaseDriver) Key(key string) string {
if l.opt.Prefix != "" { if l.opt.Prefix != "" {

View File

@@ -12,6 +12,7 @@ import (
// FileCache definition. // FileCache definition.
type FileCache struct { type FileCache struct {
BaseDriver
// caches in memory // caches in memory
MemoryCache MemoryCache
// cache directory path // cache directory path
@@ -81,7 +82,7 @@ func (c *FileCache) get(key string) interface{} {
} }
item := &Item{} item := &Item{}
if err = c.MustUnmarshal(bs, item); err != nil { if err = c.UnmarshalTo(bs, item); err != nil {
c.SetLastErr(err) c.SetLastErr(err)
return nil return nil
} }

View File

@@ -7,7 +7,6 @@ import (
// MemoryCache definition. // MemoryCache definition.
type MemoryCache struct { type MemoryCache struct {
BaseDriver
// locker // locker
lock sync.RWMutex lock sync.RWMutex
// cache data in memory. or use sync.Map // cache data in memory. or use sync.Map
@@ -55,8 +54,8 @@ func (c *MemoryCache) Get(key string) interface{} {
func (c *MemoryCache) get(key string) interface{} { func (c *MemoryCache) get(key string) interface{} {
if item, ok := c.caches[key]; ok { if item, ok := c.caches[key]; ok {
// check expire time // check expire time
if item.Invalid() {
// if has been expired, remove it. // if has been expired, remove it.
if item.Invalid() {
_ = c.del(key) _ = c.del(key)
} }
@@ -103,37 +102,37 @@ func (c *MemoryCache) del(key string) error {
// GetMulti values by multi key // GetMulti values by multi key
func (c *MemoryCache) GetMulti(keys []string) map[string]interface{} { func (c *MemoryCache) GetMulti(keys []string) map[string]interface{} {
c.lock.RLock() c.lock.RLock()
defer c.lock.RUnlock()
values := make(map[string]interface{}, len(keys)) data := make(map[string]interface{}, len(keys))
for _, key := range keys { for _, key := range keys {
values[key] = c.get(key) data[key] = c.get(key)
} }
return values c.lock.RUnlock()
return data
} }
// SetMulti values by multi key // SetMulti values by multi key
func (c *MemoryCache) SetMulti(values map[string]interface{}, ttl time.Duration) (err error) { func (c *MemoryCache) SetMulti(values map[string]interface{}, ttl time.Duration) (err error) {
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
for key, val := range values { for key, val := range values {
if err = c.set(key, val, ttl); err != nil { if err = c.set(key, val, ttl); err != nil {
return return
} }
} }
c.lock.Unlock()
return return
} }
// DelMulti values by multi key // DelMulti values by multi key
func (c *MemoryCache) DelMulti(keys []string) error { func (c *MemoryCache) DelMulti(keys []string) error {
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
for _, key := range keys { for _, key := range keys {
_ = c.del(key) _ = c.del(key)
} }
c.lock.Unlock()
return nil return nil
} }

View File

@@ -1,13 +1,12 @@
package cache_test package cache_test
import ( import (
"math/rand"
"strconv"
"testing" "testing"
"time" "time"
"github.com/gookit/cache" "github.com/gookit/cache"
"github.com/gookit/goutil/dump" "github.com/gookit/goutil/dump"
"github.com/gookit/goutil/strutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -38,7 +37,6 @@ type user struct {
func TestMemoryCache_object(t *testing.T) { func TestMemoryCache_object(t *testing.T) {
is := assert.New(t) is := assert.New(t)
b1 := user { b1 := user {
Age: 1, Age: 1,
Name: "inhere", Name: "inhere",
@@ -46,8 +44,9 @@ func TestMemoryCache_object(t *testing.T) {
c := cache.NewMemoryCache() c := cache.NewMemoryCache()
key := randomKey() key := strutil.RandomCharsV2(12)
t.Log("cache key:", key) dump.P("cache key: " + key)
is.False(c.Has(key)) is.False(c.Has(key))
err := c.Set(key, b1, cache.Seconds3) err := c.Set(key, b1, cache.Seconds3)
@@ -110,8 +109,8 @@ func TestFileCache_object(t *testing.T) {
Name: "inhere", Name: "inhere",
} }
key := randomKey() key := strutil.RandomCharsV2(12)
dump.P("cache key:", c.Key(key)) dump.P("cache key: " + c.Key(key))
err := c.Set(key, b1, cache.Seconds3) err := c.Set(key, b1, cache.Seconds3)
is.NoError(err) is.NoError(err)
@@ -123,8 +122,3 @@ func TestFileCache_object(t *testing.T) {
// val2 := c.GetAs() // val2 := c.GetAs()
// dump.P("cache get:", val) // dump.P("cache get:", val)
} }
func randomKey() string {
rand.Seed(time.Now().UnixNano())
return "k" + time.Now().Format("20060102") + strconv.Itoa(rand.Intn(999))
}

View File

@@ -2,19 +2,78 @@
package gcache package gcache
import ( import (
"time"
"github.com/bluele/gcache" "github.com/bluele/gcache"
"github.com/gookit/cache"
) )
// GCache driver definition // GCache driver definition
type GCache struct { type GCache struct {
cache.BaseDriver // cache.BaseDriver
db gcache.Cache db gcache.Cache
} }
// New create an instance // New create an instance
func New(size int) *GCache { func New(size int) *GCache {
return NewWithType(size, gcache.TYPE_LRU)
}
// NewWithType create an instance with cache type
func NewWithType(size int, tp string) *GCache {
return &GCache{ return &GCache{
db: gcache.New(size).LRU().Build(), db: gcache.New(size).EvictType(tp).Build(),
} }
} }
// Close connection
func (g *GCache) Close() error {
return nil
}
// Clear all caches
func (g *GCache) Clear() error {
g.db.Purge()
return nil
}
// Has cache key
func (g *GCache) Has(key string) bool {
return g.Get(key) != nil
}
// Get cache by key
func (g *GCache) Get(key string) interface{} {
val, _ := g.db.Get(key)
return val
}
// Set cache by key
func (g *GCache) Set(key string, val interface{}, ttl time.Duration) (err error) {
return g.db.SetWithExpire(key, val, ttl)
}
// Del cache by key
func (g GCache) Del(key string) error {
g.db.Remove(key)
return nil
}
// GetMulti cache by keys
func (g *GCache) GetMulti(keys []string) map[string]interface{} {
panic("implement me")
}
// SetMulti cache by keys
func (g GCache) SetMulti(values map[string]interface{}, ttl time.Duration) (err error) {
panic("implement me")
}
// DelMulti cache by keys
func (g *GCache) DelMulti(keys []string) error {
panic("implement me")
}
// Db get the gcache.Cache
func (g *GCache) Db() gcache.Cache {
return g.db
}

2
go.mod
View File

@@ -12,7 +12,7 @@ require (
github.com/golang/snappy v0.0.1 // indirect github.com/golang/snappy v0.0.1 // indirect
github.com/gomodule/redigo v2.0.0+incompatible github.com/gomodule/redigo v2.0.0+incompatible
github.com/gookit/goutil v0.3.14 github.com/gookit/goutil v0.3.14
github.com/gookit/gsr v0.0.3 github.com/gookit/gsr v0.0.4
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0

2
go.sum
View File

@@ -73,6 +73,8 @@ github.com/gookit/goutil v0.3.14 h1:ZEdZR+Vkvcjz0SSC0MpjtD+Kwlg/uagpiddh6L2ko+0=
github.com/gookit/goutil v0.3.14/go.mod h1:YdGV0ObqRUlRq4/RzAQBHcd1Wzl/jKw7cppDBtD3q+U= github.com/gookit/goutil v0.3.14/go.mod h1:YdGV0ObqRUlRq4/RzAQBHcd1Wzl/jKw7cppDBtD3q+U=
github.com/gookit/gsr v0.0.3 h1:aoVIw50rSPn7TuTfY6tNJ0iysnGKKnArfRdeXQaSeME= github.com/gookit/gsr v0.0.3 h1:aoVIw50rSPn7TuTfY6tNJ0iysnGKKnArfRdeXQaSeME=
github.com/gookit/gsr v0.0.3/go.mod h1:oCrmIEBod7DNBBFP5sckUY2yrOmJgNpG3xyxryLyJKY= github.com/gookit/gsr v0.0.3/go.mod h1:oCrmIEBod7DNBBFP5sckUY2yrOmJgNpG3xyxryLyJKY=
github.com/gookit/gsr v0.0.4 h1:wxwbcwN0iSovauty6IIR2Qi7fM5Ck1NrrDKE1wU9EQ8=
github.com/gookit/gsr v0.0.4/go.mod h1:oCrmIEBod7DNBBFP5sckUY2yrOmJgNpG3xyxryLyJKY=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=

View File

@@ -1,34 +1,48 @@
// Package gocache is a memory cache driver implement.
// base on the package: github.com/patrickmn/go-cache
//
// Usage:
// import "github.com/gookit/cache"
//
// cache.Register(gocache.NewGoCache(0, cache.FiveMinutes))
// // use
// // cache.Set("key", "value")
package gocache package gocache
import ( import (
"time" "time"
"github.com/gookit/cache"
goc "github.com/patrickmn/go-cache" goc "github.com/patrickmn/go-cache"
) )
// Name driver name
const Name = "gocache"
// GoCache struct // GoCache struct
type GoCache struct { type GoCache struct {
cache.BaseDriver db *goc.Cache
cache *goc.Cache // will handle expire on has,get
// expire handle
expireManually bool expireManually bool
} }
// New create instance // New create instance
func New() *GoCache { func New() *GoCache {
c := goc.New(goc.NoExpiration, goc.NoExpiration) return NewSimple()
}
// NewSimple create new simple instance
func NewSimple() *GoCache {
return &GoCache{ return &GoCache{
cache: c, db: goc.New(goc.NoExpiration, goc.NoExpiration),
// handle expire on has,get
expireManually: true, expireManually: true,
} }
} }
// NewGoCache create instance with settings // NewGoCache create instance with settings
func NewGoCache(defaultExpiration, cleanupInterval time.Duration) *GoCache { func NewGoCache(defaultExpiration, cleanupInterval time.Duration) *GoCache {
c := goc.New(defaultExpiration, cleanupInterval)
return &GoCache{ return &GoCache{
cache: c, db: goc.New(defaultExpiration, cleanupInterval),
} }
} }
@@ -39,7 +53,7 @@ func (g *GoCache) Close() error {
// Clear all caches // Clear all caches
func (g *GoCache) Clear() error { func (g *GoCache) Clear() error {
g.cache.Flush() g.db.Flush()
return nil return nil
} }
@@ -51,32 +65,56 @@ func (g *GoCache) Has(key string) bool {
// Get cache by key // Get cache by key
func (g *GoCache) Get(key string) interface{} { func (g *GoCache) Get(key string) interface{} {
if g.expireManually { if g.expireManually {
g.cache.DeleteExpired() g.db.DeleteExpired()
} }
val, _ := g.cache.Get(key)
val, _ := g.db.Get(key)
return val return val
} }
// Set cache by key // Set cache by key
func (g *GoCache) Set(key string, val interface{}, ttl time.Duration) (err error) { func (g *GoCache) Set(key string, val interface{}, ttl time.Duration) error {
g.cache.Set(key, val, ttl) g.db.Set(key, val, ttl)
return nil return nil
} }
// Del cache by key // Del cache by key
func (g GoCache) Del(key string) error { func (g GoCache) Del(key string) error {
g.cache.Delete(key) g.db.Delete(key)
return nil return nil
} }
// GetMulti cache by keys
func (g *GoCache) GetMulti(keys []string) map[string]interface{} { func (g *GoCache) GetMulti(keys []string) map[string]interface{} {
panic("implement me") data := make(map[string]interface{}, len(keys))
for _, key := range keys {
val, ok := g.db.Get(key)
if ok {
data[key] = val
}
} }
func (g GoCache) SetMulti(values map[string]interface{}, ttl time.Duration) (err error) { return data
panic("implement me")
} }
// SetMulti cache by keys
func (g GoCache) SetMulti(values map[string]interface{}, ttl time.Duration) error {
for key, val := range values {
g.db.Set(key, val, ttl)
}
return nil
}
// DelMulti db by keys
func (g *GoCache) DelMulti(keys []string) error { func (g *GoCache) DelMulti(keys []string) error {
panic("implement me") for _, key := range keys {
g.db.Delete(key)
}
return nil
}
// Db get the goc.Cache
func (g *GoCache) Db() *goc.Cache {
return g.db
} }

View File

@@ -1,16 +1,23 @@
package gocache package gocache_test
import ( import (
"fmt" "fmt"
"testing"
"time" "time"
"github.com/gookit/cache"
"github.com/gookit/cache/gocache"
"github.com/gookit/goutil/dump"
"github.com/gookit/goutil/strutil"
"github.com/stretchr/testify/assert"
) )
func ExampleGoCache() { func ExampleGoCache() {
c := New() c := gocache.New()
key := "name" key := "name"
// set // set
c.Set(key, "cache value", 2*time.Second) c.Set(key, "cache value", cache.Seconds2)
fmt.Println(c.Has(key)) fmt.Println(c.Has(key))
// get // get
@@ -33,3 +40,84 @@ func ExampleGoCache() {
// <nil> // <nil>
// false // false
} }
func ExampleNewGoCache_cachePkg() {
c1 := gocache.NewGoCache(cache.OneDay, cache.FiveMinutes)
cache.Register(gocache.Name, c1)
defer cache.UnregisterAll()
key := "name1"
// set
cache.Set(key, "cache value", cache.Seconds2)
fmt.Println(cache.Has(key))
// get
val := cache.Get(key)
fmt.Println(val)
time.Sleep(2 * time.Second)
// get expired
val2 := cache.Get(key)
fmt.Println(val2)
// del
cache.Del(key)
fmt.Println(cache.Has(key))
// Output:
// true
// cache value
// <nil>
// false
}
func TestGoCache_usage(t *testing.T) {
is := assert.New(t)
c := gocache.NewSimple()
defer c.Clear()
key := strutil.RandomCharsV2(12)
is.False(c.Has(key))
err := c.Set(key, "value", cache.Seconds3)
is.NoError(err)
is.True(c.Has(key))
val := c.Get(key)
is.Equal("value", val)
// del
err = c.Del(key)
is.NoError(err)
is.False(c.Has(key))
}
type user struct {
Age int
Name string
}
func TestGoCache_object(t *testing.T) {
is := assert.New(t)
c := gocache.NewSimple()
defer c.Clear()
b1 := user {
Age: 1,
Name: "inhere",
}
key := strutil.RandomCharsV2(12)
dump.P("cache key: " + key)
is.False(c.Has(key))
err := c.Set(key, b1, cache.Seconds3)
is.NoError(err)
is.True(c.Has(key))
b2 := c.Get(key).(user)
dump.P(b2)
is.Equal("inhere", b2.Name)
}

View File

@@ -96,6 +96,16 @@ func (c *GoRedis) Get(key string) interface{} {
return c.Unmarshal(bts, err) return c.Unmarshal(bts, err)
} }
// GetAs get cache and unmarshal to ptr
func (c *GoRedis) GetAs(key string, ptr interface{}) error {
bts, err := c.rdb.Get(CtxForExec, c.Key(key)).Bytes()
if err != nil {
return err
}
return c.UnmarshalTo(bts, ptr)
}
// Set cache by key // Set cache by key
func (c *GoRedis) Set(key string, val interface{}, ttl time.Duration) (err error) { func (c *GoRedis) Set(key string, val interface{}, ttl time.Duration) (err error) {
val, err = c.Marshal(val) val, err = c.Marshal(val)

View File

@@ -2,14 +2,12 @@ package goredis_test
import ( import (
"fmt" "fmt"
"math/rand"
"strconv"
"testing" "testing"
"time"
"github.com/gookit/cache" "github.com/gookit/cache"
"github.com/gookit/cache/goredis" "github.com/gookit/cache/goredis"
"github.com/gookit/goutil/dump" "github.com/gookit/goutil/dump"
"github.com/gookit/goutil/strutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -46,8 +44,9 @@ func getC() *goredis.GoRedis {
func TestGoRedis_basic(t *testing.T) { func TestGoRedis_basic(t *testing.T) {
c := getC() c := getC()
key := randomKey() key := strutil.RandomCharsV2(12)
t.Log("cache key", key) dump.P("cache key: " + c.Key(key))
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
err := c.Set(key, "value", cache.Seconds3) err := c.Set(key, "value", cache.Seconds3)
@@ -69,32 +68,33 @@ type user struct {
func TestRedigo_object(t *testing.T) { func TestRedigo_object(t *testing.T) {
c := getC() c := getC()
b1 := user { u1 := user {
Age: 12, Age: 12,
Name: "inhere", Name: "inhere",
} }
key := randomKey() key := strutil.RandomCharsV2(12)
t.Log("cache key", c.Key(key)) dump.P("cache key: " + c.Key(key))
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
err := c.Set(key, b1, cache.Seconds3) err := c.Set(key, u1, cache.Seconds3)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, c.Has(key)) assert.True(t, c.Has(key))
v := c.Get(key) v := c.Get(key)
assert.NotEmpty(t, v) assert.NotEmpty(t, v)
// dump.P(v.(string))
dump.P(v) dump.P(v)
u2 := user{}
err = c.GetAs(key, &u2)
assert.NoError(t, err)
dump.P(u2)
assert.Equal(t, "inhere", u2.Name)
err = c.Del(key) err = c.Del(key)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
assert.Empty(t, c.Get(key)) assert.Empty(t, c.Get(key))
} }
func randomKey() string {
return time.Now().Format("20060102") + strconv.Itoa(rand.Intn(999))
}

View File

@@ -4,13 +4,12 @@ package leveldb
import ( import (
"time" "time"
"github.com/gookit/cache"
"github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb"
) )
// LevelDB definition // LevelDB definition
type LevelDB struct { type LevelDB struct {
cache.BaseDriver // cache.BaseDriver
db *leveldb.DB db *leveldb.DB
} }

View File

@@ -29,7 +29,26 @@ type Manager struct {
func NewManager() *Manager { func NewManager() *Manager {
return &Manager{ return &Manager{
// defName: driverName, // defName: driverName,
drivers: make(map[string]Cache), drivers: make(map[string]Cache, 8),
}
}
// Register new cache driver
func (m *Manager) Register(name string, driver Cache) *Manager {
// always use latest as default driver.
m.defName = name
// save driver instance
m.drivers[name] = driver
return m
}
// Unregister an cache driver
func (m *Manager) Unregister(name string) {
delete(m.drivers, name)
// reset default driver name.
if m.defName == name {
m.defName = ""
} }
} }
@@ -37,23 +56,25 @@ func NewManager() *Manager {
// Deprecated // Deprecated
// please use DefaultUse() instead it // please use DefaultUse() instead it
func (m *Manager) SetDefName(driverName string) { func (m *Manager) SetDefName(driverName string) {
m.defName = driverName m.DefaultUse(driverName)
} }
// DefaultUse set default driver name // DefaultUse set default driver name
func (m *Manager) DefaultUse(driverName string) { func (m *Manager) DefaultUse(driverName string) {
m.defName = driverName if _, ok := m.drivers[driverName]; !ok {
panic("cache driver: " + driverName + " is not registered")
} }
// Register new driver object m.defName = driverName
func (m *Manager) Register(name string, driver Cache) *Manager {
m.drivers[name] = driver
return m
} }
// Default returns the default driver instance // Default returns the default driver instance
func (m *Manager) Default() Cache { func (m *Manager) Default() Cache {
return m.drivers[m.defName] if c, ok := m.drivers[m.defName]; ok {
return c
}
panic("cache driver: " + m.defName + " is not registered")
} }
// Use driver object by name and set it as default driver. // Use driver object by name and set it as default driver.
@@ -62,7 +83,7 @@ func (m *Manager) Use(driverName string) Cache {
return m.Driver(driverName) return m.Driver(driverName)
} }
// Cache driver object by name. alias of Driver() // Cache get driver by name. alias of Driver()
func (m *Manager) Cache(driverName string) Cache { func (m *Manager) Cache(driverName string) Cache {
return m.drivers[driverName] return m.drivers[driverName]
} }
@@ -85,6 +106,19 @@ func (m *Manager) Close() (err error) {
return err return err
} }
// UnregisterAll cache drivers
func (m *Manager) UnregisterAll(fn ...func(cache Cache)) {
m.defName = ""
for name, driver := range m.drivers {
if len(fn) > 0 {
fn[0](driver)
}
delete(m.drivers, name)
}
}
/************************************************************* /*************************************************************
* Quick use by default cache driver * Quick use by default cache driver
*************************************************************/ *************************************************************/

View File

@@ -50,7 +50,7 @@ func (c *MemCached) Get(key string) (val interface{}) {
return return
} }
err = c.MustUnmarshal(item.Value, &val) err = c.UnmarshalTo(item.Value, &val)
if err != nil { if err != nil {
return nil return nil
} }
@@ -89,7 +89,7 @@ func (c *MemCached) GetMulti(keys []string) map[string]interface{} {
values := make(map[string]interface{}, len(keys)) values := make(map[string]interface{}, len(keys))
for key, item := range items { for key, item := range items {
var val interface{} var val interface{}
if err := c.MustUnmarshal(item.Value, &val); err != nil { if err := c.UnmarshalTo(item.Value, &val); err != nil {
continue continue
} }

View File

@@ -3,13 +3,11 @@ package nutsdb
import ( import (
"time" "time"
"github.com/gookit/cache"
) )
// NutsDB definition // NutsDB definition TODO
type NutsDB struct { type NutsDB struct {
cache.BaseDriver // cache.BaseDriver
} }
func (c *NutsDB) Has(key string) bool { func (c *NutsDB) Has(key string) bool {

View File

@@ -56,9 +56,19 @@ func (c *Redigo) Connect() *Redigo {
// Get value by key // Get value by key
func (c *Redigo) Get(key string) interface{} { func (c *Redigo) Get(key string) interface{} {
val, err := redis.Bytes(c.exec("Get", c.Key(key))) bts, err := redis.Bytes(c.exec("Get", c.Key(key)))
return c.Unmarshal(val, err) return c.Unmarshal(bts, err)
}
// GetAs get cache and unmarshal to ptr
func (c *Redigo) GetAs(key string, ptr interface{}) error {
bts, err := redis.Bytes(c.exec("Get", c.Key(key)))
if err != nil {
return err
}
return c.UnmarshalTo(bts, ptr)
} }
// Set value by key // Set value by key

View File

@@ -2,14 +2,12 @@ package redis_test
import ( import (
"fmt" "fmt"
"math/rand"
"strconv"
"testing" "testing"
"time"
"github.com/gookit/cache" "github.com/gookit/cache"
"github.com/gookit/cache/redis" "github.com/gookit/cache/redis"
"github.com/gookit/goutil/dump" "github.com/gookit/goutil/dump"
"github.com/gookit/goutil/strutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -45,8 +43,9 @@ func getC() *redis.Redigo {
func TestRedigo_basic(t *testing.T) { func TestRedigo_basic(t *testing.T) {
c := getC() c := getC()
key := randomKey() key := strutil.RandomCharsV2(12)
t.Log("cache key", c.Key(key)) dump.P("cache key: " + c.Key(key))
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
err := c.Set(key, "value", cache.Seconds3) err := c.Set(key, "value", cache.Seconds3)
@@ -72,8 +71,9 @@ func TestRedigo_object(t *testing.T) {
Name: "inhere", Name: "inhere",
} }
key := randomKey() key := strutil.RandomCharsV2(12)
t.Log("cache key", c.Key(key)) dump.P("cache key: " + c.Key(key))
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
err := c.Set(key, b1, cache.Seconds3) err := c.Set(key, b1, cache.Seconds3)
@@ -83,16 +83,16 @@ func TestRedigo_object(t *testing.T) {
v := c.Get(key) v := c.Get(key)
assert.NotEmpty(t, v) assert.NotEmpty(t, v)
// dump.P(v.(string))
dump.P(v) dump.P(v)
u2 := user{}
err = c.GetAs(key, &u2)
assert.NoError(t, err)
dump.P(u2)
assert.Equal(t, "inhere", u2.Name)
err = c.Del(key) err = c.Del(key)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, c.Has(key)) assert.False(t, c.Has(key))
assert.Empty(t, c.Get(key)) assert.Empty(t, c.Get(key))
} }
func randomKey() string {
return "k" + time.Now().Format("20060102") + strconv.Itoa(rand.Intn(999))
}