mirror of
https://github.com/gookit/cache.git
synced 2025-10-04 15:52:50 +08:00
add more manage methods. modify some cache logic
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
11
cache.go
11
cache.go
@@ -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
|
||||||
|
14
driver.go
14
driver.go
@@ -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 != "" {
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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 has been expired, remove it.
|
||||||
if item.Invalid() {
|
if item.Invalid() {
|
||||||
// if has been expired, remove it.
|
|
||||||
_ = 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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))
|
|
||||||
}
|
|
||||||
|
@@ -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
2
go.mod
@@ -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
2
go.sum
@@ -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=
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g GoCache) SetMulti(values map[string]interface{}, ttl time.Duration) (err error) {
|
// SetMulti cache by keys
|
||||||
panic("implement me")
|
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
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
}
|
@@ -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)
|
||||||
|
@@ -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))
|
|
||||||
}
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
manager.go
54
manager.go
@@ -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
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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
|
||||||
|
@@ -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))
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user