- init
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

master v1.0.0
李光春 2 years ago
commit 8a3b3100f8

@ -0,0 +1,17 @@
kind: pipeline
type: docker
name: clone
steps:
- name: Test
image: golang:1.18
commands:
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.cn,direct
- go test -v ./...
- name: Benchmark
image: golang:1.18
commands:
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.cn,direct
- go test -bench=. -benchmem

9
.gitignore vendored

@ -0,0 +1,9 @@
.env
.git
.svn
.idea
.vscode
*.log
goinit.sh
gomod.sh
/vendor/

@ -0,0 +1,26 @@
package goredis
type Iterator struct {
data []interface{}
index int
}
// NewIterator 构造函数
func NewIterator(data []interface{}) *Iterator {
return &Iterator{data: data}
}
// HasNext 是否有下一个
func (i *Iterator) HasNext() bool {
if i.data == nil || len(i.data) == 0 {
return false
}
return i.index < len(i.data)
}
// Next 循环下一个
func (i *Iterator) Next() (Ret interface{}) {
Ret = i.data[i.index]
i.index = i.index + 1
return
}

@ -0,0 +1,45 @@
package goredis
import (
"context"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
"log"
"time"
)
// App 实例
type App struct {
Db *redis.Client
Addr string // 地址
Password string // 密码
DB int // 数据库
PoolSize int // 连接池大小
}
// InitClient 初始化连接
func (app *App) InitClient() {
log.Printf("redis config%+v\n", app)
if app.PoolSize == 0 {
app.PoolSize = 100
}
app.Db = redis.NewClient(&redis.Options{
Addr: app.Addr, // 地址
Password: app.Password, // 密码
DB: app.DB, // 数据库
PoolSize: app.PoolSize, // 连接池大小
})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err := app.Db.Ping(ctx).Result()
if err != nil {
panic(errors.New(fmt.Sprintf("数据库【redis】连接失败%v", err)))
}
return
}

@ -0,0 +1,13 @@
module go.dtapp.net/goredis
go 1.18
require (
github.com/go-redis/redis/v8 v8.11.5
go.dtapp.net/gotime v1.0.2
)
require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
)

@ -0,0 +1,17 @@
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
go.dtapp.net/gotime v1.0.2 h1:CFIJHQXC/4t9bsJhk2cLhjHd6rpdPcJXr8BcHKHDuQo=
go.dtapp.net/gotime v1.0.2/go.mod h1:Gq7eNLr2iMLP18UNWONRq4V3Uhf/ADp4bIrS+Tc6ktY=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=

@ -0,0 +1,26 @@
package goredis
import (
"context"
"github.com/go-redis/redis/v8"
)
type HashOperation struct {
db *redis.Client
ctx context.Context
}
// NewHashOperation hash类型数据操作 https://www.tizi365.com/archives/296.html
func NewHashOperation(db *redis.Client, ctx context.Context) *HashOperation {
return &HashOperation{db: db, ctx: ctx}
}
// Set 根据key和field字段设置field字段的值
func (cl *HashOperation) Set(key string, value interface{}) *redis.IntCmd {
return cl.db.HSet(cl.ctx, key, value)
}
// Get 根据key和field字段设置field字段的值
func (cl *HashOperation) Get(key, field string) *redis.StringCmd {
return cl.db.HGet(cl.ctx, key, field)
}

@ -0,0 +1,76 @@
package goredis
import (
"context"
"github.com/go-redis/redis/v8"
)
type ListOperation struct {
db *redis.Client
ctx context.Context
}
// NewListOperation 列表(list)类型数据操作 https://www.tizi365.com/archives/299.html
func (app *App) NewListOperation() *ListOperation {
return &ListOperation{db: app.Db, ctx: context.Background()}
}
// LPush 从列表左边插入数据
func (cl *ListOperation) LPush(key string, value interface{}) *redis.IntCmd {
return cl.db.LPush(cl.ctx, key, value)
}
// LPushX 跟LPush的区别是仅当列表存在的时候才插入数据
func (cl *ListOperation) LPushX(key string, value interface{}) *redis.IntCmd {
return cl.db.LPushX(cl.ctx, key, value)
}
// RPop 从列表的右边删除第一个数据,并返回删除的数据
func (cl *ListOperation) RPop(key string) *redis.StringCmd {
return cl.db.RPop(cl.ctx, key)
}
// RPush 从列表右边插入数据
func (cl *ListOperation) RPush(key string, value interface{}) *redis.IntCmd {
return cl.db.RPush(cl.ctx, key, value)
}
// RPushX 跟RPush的区别是仅当列表存在的时候才插入数据
func (cl *ListOperation) RPushX(key string, value interface{}) *redis.IntCmd {
return cl.db.RPushX(cl.ctx, key, value)
}
// LPop 从列表左边删除第一个数据,并返回删除的数据
func (cl *ListOperation) LPop(key string) *redis.StringCmd {
return cl.db.LPop(cl.ctx, key)
}
// Len 返回列表的大小
func (cl *ListOperation) Len(key string) *redis.IntCmd {
return cl.db.LLen(cl.ctx, key)
}
// Range 返回列表的一个范围内的数据,也可以返回全部数据
func (cl *ListOperation) Range(key string, start, stop int64) *redis.StringSliceCmd {
return cl.db.LRange(cl.ctx, key, start, stop)
}
// RangeAli 返回key全部数据
func (cl *ListOperation) RangeAli(key string) *redis.StringSliceCmd {
return cl.db.LRange(cl.ctx, key, 0, -1)
}
// Rem 删除key中的数据
func (cl *ListOperation) Rem(key string, count int64, value interface{}) *redis.IntCmd {
return cl.db.LRem(cl.ctx, key, count, value)
}
// Index 根据索引坐标查询key中的数据
func (cl *ListOperation) Index(key string, index int64) *redis.StringCmd {
return cl.db.LIndex(cl.ctx, key, index)
}
// Insert 在指定位置插入数据
func (cl *ListOperation) Insert(key, op string, pivot, value interface{}) *redis.IntCmd {
return cl.db.LInsert(cl.ctx, key, op, pivot, value)
}

@ -0,0 +1,35 @@
package goredis
import "time"
type empty struct{}
const (
AttrExpr = "expr" // 过期时间
AttrNx = "nx" // 设置Nx
)
type OperationAttr struct {
Name string
Value interface{}
}
type OperationAttrs []*OperationAttr
func (a OperationAttrs) Find(name string) interface{} {
for _, attr := range a {
if attr.Name == name {
return attr.Value
}
}
return nil
}
// WithExpire 过期时间
func WithExpire(t time.Duration) *OperationAttr {
return &OperationAttr{Name: AttrExpr, Value: t}
}
func WithNX() *OperationAttr {
return &OperationAttr{Name: AttrNx, Value: empty{}}
}

@ -0,0 +1,61 @@
package goredis
import (
"encoding/json"
"time"
)
const (
SerializerJson = "json"
SerializerString = "string"
)
type JsonGttFunc func() interface{}
type DBGttFunc func() string
// SimpleCache 缓存
type SimpleCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过去时间
DBGetter DBGttFunc // 缓存不存在的操作 DB
JsonGetter JsonGttFunc // 缓存不存在的操作 JSON
Serializer string // 序列化方式
}
// NewSimpleCache 构造函数
func (app *App) NewSimpleCache(operation *StringOperation, expire time.Duration, serializer string) *SimpleCache {
return &SimpleCache{
Operation: operation, // 操作类
Expire: expire, // 过去时间
Serializer: serializer, // 缓存不存在的操作 DB
}
}
// SetCache 设置缓存
func (c *SimpleCache) SetCache(key string, value interface{}) {
c.Operation.Set(key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleCache) GetCache(key string) (ret interface{}) {
if c.Serializer == SerializerJson {
f := func() string {
obj := c.JsonGetter()
b, err := json.Marshal(obj)
if err != nil {
return ""
}
return string(b)
}
ret = c.Operation.Get(key).UnwrapOrElse(f)
c.SetCache(key, ret)
} else if c.Serializer == SerializerString {
f := func() string {
return c.DBGetter()
}
ret = c.Operation.Get(key).UnwrapOrElse(f)
c.SetCache(key, ret)
}
return
}

@ -0,0 +1,39 @@
package goredis
import (
"log"
"time"
)
type DBGttInterfaceFunc func() interface{}
// SimpleInterfaceCache 缓存
type SimpleInterfaceCache struct {
Operation *SimpleOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttInterfaceFunc // 缓存不存在的操作 DB
}
// NewSimpleInterfaceCache 构造函数
func (app *App) NewSimpleInterfaceCache(operation *SimpleOperation, expire time.Duration) *SimpleInterfaceCache {
return &SimpleInterfaceCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleInterfaceCache) SetCache(key string, value interface{}) {
c.Operation.Set(key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleInterfaceCache) GetCache(key string) (ret interface{}) {
f := func() interface{} {
return c.DBGetter()
}
ret = c.Operation.Get(key).UnwrapOrElse(f)
c.SetCache(key, ret)
log.Println(ret)
return ret
}

@ -0,0 +1,43 @@
package goredis
import (
"encoding/json"
"time"
)
type DBGttJsonFunc func() interface{}
// SimpleJsonCache 缓存
type SimpleJsonCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttJsonFunc // 缓存不存在的操作 DB
}
// NewSimpleJsonCache 构造函数
func (app *App) NewSimpleJsonCache(operation *StringOperation, expire time.Duration) *SimpleJsonCache {
return &SimpleJsonCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleJsonCache) SetCache(key string, value interface{}) {
c.Operation.Set(key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleJsonCache) GetCache(key string) (ret interface{}) {
f := func() string {
obj := c.DBGetter()
b, err := json.Marshal(obj)
if err != nil {
return ""
}
return string(b)
}
ret = c.Operation.Get(key).UnwrapOrElse(f)
c.SetCache(key, ret)
return
}

@ -0,0 +1,38 @@
package goredis
import (
"context"
"github.com/go-redis/redis/v8"
"time"
)
type SimpleOperation struct {
db *redis.Client
ctx context.Context
}
func (app *App) NewSimpleOperation() *SimpleOperation {
return &SimpleOperation{
db: app.Db,
ctx: context.Background(),
}
}
// Set 设置
func (o *SimpleOperation) Set(key string, value interface{}, attrs ...*OperationAttr) *SimpleResult {
exp := OperationAttrs(attrs).Find(AttrExpr)
if exp == nil {
exp = time.Second * 0
}
return NewSimpleResult(o.db.Set(o.ctx, key, value, exp.(time.Duration)).Result())
}
// Get 获取单个
func (o *SimpleOperation) Get(key string) *SimpleResult {
return NewSimpleResult(o.db.Get(o.ctx, key).Result())
}
// Del 删除key操作支持批量删除
func (o *SimpleOperation) Del(keys ...string) *redis.IntCmd {
return o.db.Del(o.ctx, keys...)
}

@ -0,0 +1,35 @@
package goredis
type SimpleResult struct {
Result interface{}
Err error
}
// NewSimpleResult 构造函数
func NewSimpleResult(result interface{}, err error) *SimpleResult {
return &SimpleResult{Result: result, Err: err}
}
// Unwrap 空值情况下返回错误
func (r *SimpleResult) Unwrap() interface{} {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *SimpleResult) UnwrapOr(defaults interface{}) interface{} {
if r.Err != nil {
return defaults
}
return r.Result
}
// UnwrapOrElse 空值情况下设置返回其他
func (r *SimpleResult) UnwrapOrElse(f func() interface{}) interface{} {
if r.Err != nil {
return f()
}
return r.Result
}

@ -0,0 +1,37 @@
package goredis
import (
"time"
)
type DBGttStringFunc func() string
// SimpleStringCache 缓存
type SimpleStringCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttStringFunc // 缓存不存在的操作 DB
}
// NewSimpleStringCache 构造函数
func (app *App) NewSimpleStringCache(operation *StringOperation, expire time.Duration) *SimpleStringCache {
return &SimpleStringCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleStringCache) SetCache(key string, value string) {
c.Operation.Set(key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleStringCache) GetCache(key string) (ret string) {
f := func() string {
return c.DBGetter()
}
ret = c.Operation.Get(key).UnwrapOrElse(f)
c.SetCache(key, ret)
return
}

@ -0,0 +1,31 @@
package goredis
type SliceResult struct {
Result []interface{}
Err error
}
// NewSliceResult 构造函数
func NewSliceResult(result []interface{}, err error) *SliceResult {
return &SliceResult{Result: result, Err: err}
}
// Unwrap 空值情况下返回错误
func (r *SliceResult) Unwrap() []interface{} {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *SliceResult) UnwrapOr(defaults []interface{}) []interface{} {
if r.Err != nil {
return defaults
}
return r.Result
}
func (r *SliceResult) Iter() *Iterator {
return NewIterator(r.Result)
}

@ -0,0 +1,43 @@
package goredis
import (
"context"
"github.com/go-redis/redis/v8"
"time"
)
type StringOperation struct {
db *redis.Client
ctx context.Context
}
func (app *App) NewStringOperation() *StringOperation {
return &StringOperation{
db: app.Db,
ctx: context.Background(),
}
}
// Set 设置
func (o *StringOperation) Set(key string, value interface{}, attrs ...*OperationAttr) *StringResult {
exp := OperationAttrs(attrs).Find(AttrExpr)
if exp == nil {
exp = time.Second * 0
}
return NewStringResult(o.db.Set(o.ctx, key, value, exp.(time.Duration)).Result())
}
// Get 获取单个
func (o *StringOperation) Get(key string) *StringResult {
return NewStringResult(o.db.Get(o.ctx, key).Result())
}
// MGet 获取多个
func (o *StringOperation) MGet(keys ...string) *SliceResult {
return NewSliceResult(o.db.MGet(o.ctx, keys...).Result())
}
// Del 删除key操作支持批量删除
func (o *StringOperation) Del(keys ...string) *redis.IntCmd {
return o.db.Del(o.ctx, keys...)
}

@ -0,0 +1,38 @@
package goredis
type StringResult struct {
Result string // 结果
Err error // 错误
}
// NewStringResult 构造函数
func NewStringResult(result string, err error) *StringResult {
return &StringResult{
Result: result,
Err: err,
}
}
// Unwrap 空值情况下返回错误
func (r *StringResult) Unwrap() string {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *StringResult) UnwrapOr(defaults string) string {
if r.Err != nil {
return defaults
}
return r.Result
}
// UnwrapOrElse 空值情况下设置返回其他
func (r *StringResult) UnwrapOrElse(f func() string) string {
if r.Err != nil {
return f()
}
return r.Result
}

@ -0,0 +1,3 @@
package goredis
const Version = "1.0.0"

@ -0,0 +1,7 @@
package goredis
import "testing"
func TestVersion(t *testing.T) {
t.Log(Version)
}
Loading…
Cancel
Save