From 7d57e1f7d2cd8688811823de4a7018c8956786e6 Mon Sep 17 00:00:00 2001 From: Kittisak Date: Sat, 17 Jun 2023 19:17:14 +0700 Subject: [PATCH] initial commit --- README.md | 1 + go.mod | 9 +++++ go.sum | 6 ++++ rdctx.go | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 rdctx.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..e53eff0 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# rdctx is a go-redis client wrapper with more features diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..940b0f3 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/dnjooiopa/rdctx + +go 1.19 + +require ( + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/redis/go-redis/v9 v9.0.5 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d23352a --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/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/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= +github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= diff --git a/rdctx.go b/rdctx.go new file mode 100644 index 0000000..1ea8996 --- /dev/null +++ b/rdctx.go @@ -0,0 +1,106 @@ +package rdctx + +import ( + "context" + "net/http" + "time" + + "github.com/redis/go-redis/v9" +) + +type Client struct { + *redis.Client +} + +func New(addr string, password string, db int) *Client { + c := redis.NewClient(&redis.Options{ + Addr: addr, + Password: password, + DB: db, + }) + return &Client{c} +} + +// connection ok if no error +func (c *Client) ConnectionOK() error { + _, err := c.Ping(context.Background()).Result() + return err +} + +type ctxKeyClient struct{} + +func NewWithContext(ctx context.Context, addr string, password string, db int) (*Client, context.Context) { + c := New(addr, password, db) + return c, NewContext(ctx, c) +} + +func NewContext(ctx context.Context, c *Client) context.Context { + return context.WithValue(ctx, ctxKeyClient{}, c) +} + +func Middleware(c *Client) func(h http.Handler) http.Handler { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r = r.WithContext(NewContext(r.Context(), c)) + h.ServeHTTP(w, r) + }) + } +} + +func c(ctx context.Context) *Client { + return ctx.Value(ctxKeyClient{}).(*Client) +} + +func SetEx(ctx context.Context, key string, value interface{}, exp time.Duration) (string, error) { + return c(ctx).Set(ctx, key, value, exp).Result() +} + +func Set(ctx context.Context, key string, value interface{}) (string, error) { + return SetEx(ctx, key, value, 0) +} + +func Del(ctx context.Context, keys ...string) (int64, error) { + return c(ctx).Del(ctx, keys...).Result() +} + +func Incr(ctx context.Context, key string) (int64, error) { + return c(ctx).Incr(ctx, key).Result() +} + +func Get(ctx context.Context, key string) (string, error) { + return c(ctx).Get(ctx, key).Result() +} + +func Expire(ctx context.Context, key string, exp time.Duration) (bool, error) { + return c(ctx).Expire(ctx, key, exp).Result() +} + +func Keys(ctx context.Context, pattern string) ([]string, error) { + return c(ctx).Keys(ctx, pattern).Result() +} + +func MGet(ctx context.Context, keys ...string) ([]interface{}, error) { + return c(ctx).MGet(ctx, keys...).Result() +} + +func Scan(ctx context.Context, cursor uint64, match string, count int64) ([]string, uint64, error) { + return c(ctx).Scan(ctx, cursor, match, count).Result() +} + +type KeyValue struct { + Key string + Value interface{} +} + +func MSetEx(ctx context.Context, keyValues []KeyValue, exp time.Duration) error { + if len(keyValues) == 0 { + return nil + } + + pipeline := c(ctx).Pipeline() + for _, v := range keyValues { + pipeline.Set(ctx, v.Key, v.Value, exp) + } + _, err := pipeline.Exec(ctx) + return err +}