init
This commit is contained in:
23
myRedis/Ierator.go
Normal file
23
myRedis/Ierator.go
Normal file
@ -0,0 +1,23 @@
|
||||
package myRedis
|
||||
|
||||
type Iterator struct {
|
||||
data []interface{}
|
||||
index int
|
||||
}
|
||||
|
||||
func NewIterator(data []interface{}) *Iterator {
|
||||
return &Iterator{data: data}
|
||||
}
|
||||
|
||||
func (t *Iterator) HasNext() bool {
|
||||
if t.data == nil || len(t.data) == 0 {
|
||||
return false
|
||||
}
|
||||
return t.index < len(t.data)
|
||||
}
|
||||
|
||||
func (t *Iterator) Next() (ret interface{}) {
|
||||
ret = t.data[t.index]
|
||||
t.index = t.index + 1
|
||||
return
|
||||
}
|
33
myRedis/IntResult.go
Normal file
33
myRedis/IntResult.go
Normal file
@ -0,0 +1,33 @@
|
||||
package myRedis
|
||||
|
||||
type IntResult struct {
|
||||
Result int64
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewIntResult(result int64, err error) *IntResult {
|
||||
return &IntResult{Result: result, Err: err}
|
||||
}
|
||||
|
||||
func (t *IntResult) Unwrap() int64 {
|
||||
if t.Err != nil {
|
||||
panic(t.Err)
|
||||
}
|
||||
|
||||
return t.Result
|
||||
}
|
||||
|
||||
func (t *IntResult) UnwrapOr(str int64) int64 {
|
||||
if t.Err != nil {
|
||||
return str
|
||||
} else {
|
||||
return t.Result
|
||||
}
|
||||
}
|
||||
|
||||
func (t *IntResult) UnwrapOrElse(f func() int64) int64 {
|
||||
if t.Err != nil {
|
||||
return f()
|
||||
}
|
||||
return t.Result
|
||||
}
|
25
myRedis/InterfaceResult.go
Normal file
25
myRedis/InterfaceResult.go
Normal file
@ -0,0 +1,25 @@
|
||||
package myRedis
|
||||
|
||||
type InterfaceResult struct {
|
||||
Result interface{}
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewInterfaceResult(result interface{}, err error) *InterfaceResult {
|
||||
return &InterfaceResult{Result: result, Err: err}
|
||||
}
|
||||
|
||||
func (t *InterfaceResult) Unwrap() interface{} {
|
||||
if t.Err != nil {
|
||||
panic(t.Err)
|
||||
}
|
||||
|
||||
return t.Result
|
||||
}
|
||||
|
||||
func (t *InterfaceResult) UnwrapOr(a interface{}) interface{} {
|
||||
if t.Err != nil {
|
||||
return a
|
||||
}
|
||||
return t.Result
|
||||
}
|
52
myRedis/OperationAttr.go
Normal file
52
myRedis/OperationAttr.go
Normal file
@ -0,0 +1,52 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
AttrExpr = "expr"
|
||||
AttrNx = "nx"
|
||||
AttrXx = "xx"
|
||||
)
|
||||
|
||||
type empty struct {
|
||||
}
|
||||
|
||||
type OperationAttr struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type OperationAttrs []*OperationAttr
|
||||
|
||||
func (t OperationAttrs) Find(name string) *InterfaceResult {
|
||||
for _, attr := range t {
|
||||
if attr.Name == name {
|
||||
return NewInterfaceResult(attr.Value, nil)
|
||||
}
|
||||
}
|
||||
return NewInterfaceResult(nil, fmt.Errorf("OperationAttrs found error:%s", name))
|
||||
}
|
||||
|
||||
func WithExpire(t time.Duration) *OperationAttr {
|
||||
return &OperationAttr{
|
||||
Name: AttrExpr,
|
||||
Value: t,
|
||||
}
|
||||
}
|
||||
|
||||
func WithNX() *OperationAttr {
|
||||
return &OperationAttr{
|
||||
Name: AttrNx,
|
||||
Value: empty{},
|
||||
}
|
||||
}
|
||||
|
||||
func WithXX() *OperationAttr {
|
||||
return &OperationAttr{
|
||||
Name: AttrXx,
|
||||
Value: empty{},
|
||||
}
|
||||
}
|
132
myRedis/SimpleCache.go
Normal file
132
myRedis/SimpleCache.go
Normal file
@ -0,0 +1,132 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
SerializerNot = ""
|
||||
SerializerJson = "json"
|
||||
SerializerGob = "gob"
|
||||
)
|
||||
|
||||
type CacheGetterFunc func() interface{}
|
||||
|
||||
type SimpleCache struct {
|
||||
Operation *StringOperation
|
||||
Expire time.Duration
|
||||
CacheGetter CacheGetterFunc
|
||||
Serializer string //序列化方式
|
||||
}
|
||||
|
||||
func NewSimpleCache(operation *StringOperation, expire time.Duration, serializer string) *SimpleCache {
|
||||
return &SimpleCache{Operation: operation, Expire: expire, Serializer: serializer}
|
||||
}
|
||||
|
||||
func (t *SimpleCache) SetCacheGetterFunc(f CacheGetterFunc) *SimpleCache {
|
||||
t.CacheGetter = f
|
||||
return t
|
||||
}
|
||||
|
||||
// 设置缓存
|
||||
func (t *SimpleCache) SetCache(key string, value interface{}) {
|
||||
//if t.Serializer == SerializerNot {
|
||||
//}
|
||||
if t.Serializer == SerializerJson {
|
||||
f := func() string {
|
||||
j, e := json.Marshal(value)
|
||||
if e != nil {
|
||||
return e.Error()
|
||||
} else {
|
||||
return string(j)
|
||||
}
|
||||
}
|
||||
t.Operation.Set(key, f(), WithExpire(t.Expire)).Unwrap()
|
||||
} else if t.Serializer == SerializerGob {
|
||||
f := func() string {
|
||||
var buf = &bytes.Buffer{}
|
||||
enc := gob.NewEncoder(buf)
|
||||
if err := enc.Encode(value); err != nil {
|
||||
return ""
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
t.Operation.Set(key, f(), WithExpire(t.Expire)).Unwrap()
|
||||
} else {
|
||||
t.Operation.Set(key, value, WithExpire(t.Expire)).Unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *SimpleCache) GetCache(key string) (ret interface{}) {
|
||||
//如果没有设置的话
|
||||
if t.CacheGetter == nil {
|
||||
panic("没有设置CacheGetter")
|
||||
}
|
||||
|
||||
if t.Serializer == SerializerNot {
|
||||
}
|
||||
if t.Serializer == SerializerJson {
|
||||
f := func() string {
|
||||
j, e := json.Marshal(t.CacheGetter())
|
||||
if e != nil {
|
||||
return e.Error()
|
||||
} else {
|
||||
return string(j)
|
||||
}
|
||||
}
|
||||
ret = t.Operation.Get(key).UnwrapOrElse(func() string {
|
||||
data := f()
|
||||
t.Operation.Set(key, data, WithExpire(t.Expire)).Unwrap()
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
if t.Serializer == SerializerGob {
|
||||
f := func() string {
|
||||
var buf = &bytes.Buffer{}
|
||||
enc := gob.NewEncoder(buf)
|
||||
if err := enc.Encode(t.CacheGetter()); err != nil {
|
||||
return ""
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
ret = t.Operation.Get(key).UnwrapOrElse(func() string {
|
||||
data := f()
|
||||
t.Operation.Set(key, data, WithExpire(t.Expire)).Unwrap()
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (t *SimpleCache) DelCache(key string) int64 {
|
||||
return t.Operation.Del(key).UnwrapOr(0)
|
||||
}
|
||||
|
||||
func (t *SimpleCache) GetCacheForObject(key string, obj interface{}) interface{} {
|
||||
ret := t.GetCache(key)
|
||||
if ret == nil {
|
||||
return nil
|
||||
}
|
||||
if t.Serializer == SerializerNot {
|
||||
obj = ret
|
||||
} else if t.Serializer == SerializerJson {
|
||||
err := json.Unmarshal([]byte(ret.(string)), obj)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
} else if t.Serializer == SerializerGob {
|
||||
|
||||
var buf = &bytes.Buffer{}
|
||||
buf.WriteString(ret.(string))
|
||||
dec := gob.NewDecoder(buf)
|
||||
if dec.Decode(obj) != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
29
myRedis/SliceResult.go
Normal file
29
myRedis/SliceResult.go
Normal file
@ -0,0 +1,29 @@
|
||||
package myRedis
|
||||
|
||||
type SliceResult struct {
|
||||
Result []interface{}
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewSliceResult(result []interface{}, err error) *SliceResult {
|
||||
return &SliceResult{Result: result, Err: err}
|
||||
}
|
||||
|
||||
func (t *SliceResult) Unwrap() []interface{} {
|
||||
if t.Err != nil {
|
||||
panic(t.Err)
|
||||
}
|
||||
return t.Result
|
||||
}
|
||||
|
||||
func (t *SliceResult) UnwrapOr(strs []interface{}) []interface{} {
|
||||
if t.Err != nil {
|
||||
return strs
|
||||
} else {
|
||||
return t.Result
|
||||
}
|
||||
}
|
||||
|
||||
func (t *SliceResult) Iter() *Iterator {
|
||||
return NewIterator(t.Result)
|
||||
}
|
52
myRedis/StringCache.go
Normal file
52
myRedis/StringCache.go
Normal file
@ -0,0 +1,52 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StringCache struct {
|
||||
Operation *StringOperation
|
||||
Expire time.Duration
|
||||
DefaultString string
|
||||
}
|
||||
|
||||
func NewStringCache(redisClient *redis.Client) *StringCache {
|
||||
return &StringCache{
|
||||
Operation: NewStringOperation(redisClient),
|
||||
Expire: time.Second * 0,
|
||||
DefaultString: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (t *StringCache) SetExpire(expire time.Duration) *StringCache {
|
||||
t.Expire = expire
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *StringCache) SetDefaultString(defaultString string) *StringCache {
|
||||
t.DefaultString = defaultString
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *StringCache) SetCache(key string, value string) {
|
||||
t.Operation.Set(key, value, WithExpire(t.Expire))
|
||||
}
|
||||
|
||||
func (t *StringCache) GetCache(key string) (ret string) {
|
||||
ret = t.Operation.Get(key).UnwrapOrElse(func() string {
|
||||
if t.DefaultString != "" {
|
||||
t.SetCache(key, t.DefaultString)
|
||||
}
|
||||
return t.DefaultString
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (t *StringCache) IsExist(key string) bool {
|
||||
return t.Operation.Exist(key).UnwrapOr(0) != 0
|
||||
}
|
||||
|
||||
func (t *StringCache) DelCache(key string) int64 {
|
||||
return t.Operation.Del(key).UnwrapOr(0)
|
||||
}
|
48
myRedis/StringOperation.go
Normal file
48
myRedis/StringOperation.go
Normal file
@ -0,0 +1,48 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StringOperation struct {
|
||||
ctx context.Context
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewStringOperation(client *redis.Client) *StringOperation {
|
||||
return &StringOperation{ctx: context.Background(), client: client}
|
||||
}
|
||||
|
||||
func (t *StringOperation) Set(key string, value interface{}, attrs ...*OperationAttr) *InterfaceResult {
|
||||
exp := OperationAttrs(attrs).Find(AttrExpr).UnwrapOr(0 * time.Second).(time.Duration)
|
||||
|
||||
nx := OperationAttrs(attrs).Find(AttrNx).UnwrapOr(nil)
|
||||
if nx != nil {
|
||||
return NewInterfaceResult(t.client.SetNX(t.ctx, key, value, exp).Result())
|
||||
}
|
||||
|
||||
xx := OperationAttrs(attrs).Find(AttrXx).UnwrapOr(nil)
|
||||
if xx != nil {
|
||||
return NewInterfaceResult(t.client.SetXX(t.ctx, key, value, exp).Result())
|
||||
}
|
||||
|
||||
return NewInterfaceResult(t.client.Set(t.ctx, key, value, exp).Result())
|
||||
}
|
||||
|
||||
func (t *StringOperation) Get(key string) *StringResult {
|
||||
return NewStringResult(t.client.Get(t.ctx, key).Result())
|
||||
}
|
||||
|
||||
func (t *StringOperation) MGet(key ...string) *SliceResult {
|
||||
return NewSliceResult(t.client.MGet(t.ctx, key...).Result())
|
||||
}
|
||||
|
||||
func (t *StringOperation) Del(key string) *IntResult {
|
||||
return NewIntResult(t.client.Del(t.ctx, key).Result())
|
||||
}
|
||||
|
||||
func (t *StringOperation) Exist(key string) *IntResult {
|
||||
return NewIntResult(t.client.Exists(t.ctx, key).Result())
|
||||
}
|
33
myRedis/StringResult.go
Normal file
33
myRedis/StringResult.go
Normal file
@ -0,0 +1,33 @@
|
||||
package myRedis
|
||||
|
||||
type StringResult struct {
|
||||
Result string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewStringResult(result string, err error) *StringResult {
|
||||
return &StringResult{Result: result, Err: err}
|
||||
}
|
||||
|
||||
func (t *StringResult) Unwrap() string {
|
||||
if t.Err != nil {
|
||||
panic(t.Err)
|
||||
}
|
||||
|
||||
return t.Result
|
||||
}
|
||||
|
||||
func (t *StringResult) UnwrapOr(str string) string {
|
||||
if t.Err != nil {
|
||||
return str
|
||||
} else {
|
||||
return t.Result
|
||||
}
|
||||
}
|
||||
|
||||
func (t *StringResult) UnwrapOrElse(f func() string) string {
|
||||
if t.Err != nil {
|
||||
return f()
|
||||
}
|
||||
return t.Result
|
||||
}
|
33
myRedis/cli.go
Normal file
33
myRedis/cli.go
Normal file
@ -0,0 +1,33 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewClient(client *redis.Client) *Client {
|
||||
if client == nil {
|
||||
panic("redis client is nil")
|
||||
}
|
||||
return &Client{client: client}
|
||||
}
|
||||
|
||||
func (t *Client) GetClient() *redis.Client {
|
||||
return t.client
|
||||
}
|
||||
|
||||
func (t *Client) NewStringCache() *StringCache {
|
||||
return NewStringCache(t.client)
|
||||
}
|
||||
|
||||
func (t *Client) NewJsonCache(expire time.Duration) *SimpleCache {
|
||||
return NewSimpleCache(NewStringOperation(t.client), expire, SerializerJson)
|
||||
}
|
||||
|
||||
func (t *Client) NewGobCache(expire time.Duration) *SimpleCache {
|
||||
return NewSimpleCache(NewStringOperation(t.client), expire, SerializerGob)
|
||||
}
|
60
myRedis/index.go
Normal file
60
myRedis/index.go
Normal file
@ -0,0 +1,60 @@
|
||||
package myRedis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type SimpleRedis struct {
|
||||
Host string
|
||||
Password string
|
||||
hosts map[int]*Hosts
|
||||
}
|
||||
|
||||
type Hosts struct {
|
||||
clientOnce sync.Once
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewSimpleRedis(host string, password string) *SimpleRedis {
|
||||
return &SimpleRedis{Host: host, Password: password, hosts: map[int]*Hosts{}}
|
||||
}
|
||||
|
||||
func (t *SimpleRedis) connectRedis(index int) *redis.Client {
|
||||
if t.hosts[index] == nil {
|
||||
t.hosts[index] = &Hosts{
|
||||
clientOnce: sync.Once{},
|
||||
client: nil,
|
||||
}
|
||||
}
|
||||
|
||||
t.hosts[index].clientOnce.Do(func() {
|
||||
redisClient := redis.NewClient(&redis.Options{
|
||||
Addr: t.Host,
|
||||
Password: t.Password, // no password set
|
||||
DB: index, // use default DB
|
||||
//连接池容量以闲置链接数量
|
||||
PoolSize: 15,
|
||||
MinIdleConns: 10,
|
||||
})
|
||||
pong, err := redisClient.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("connect error:%s", err))
|
||||
}
|
||||
log.Println(fmt.Sprintf("redis newClient success, index:%d, pong: %s", index, pong))
|
||||
|
||||
t.hosts[index].client = redisClient
|
||||
})
|
||||
return t.hosts[index].client
|
||||
}
|
||||
|
||||
func (t *SimpleRedis) ConnectDefaultRedis() *Client {
|
||||
return t.GetRedisClient(0)
|
||||
}
|
||||
|
||||
func (t *SimpleRedis) GetRedisClient(index int) *Client {
|
||||
return NewClient(t.connectRedis(index))
|
||||
}
|
Reference in New Issue
Block a user