mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
refract package gredis
This commit is contained in:
@ -14,33 +14,10 @@
|
||||
package gredis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/container/gvar"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Redis client.
|
||||
type Redis struct {
|
||||
adapter Adapter
|
||||
}
|
||||
|
||||
// Config is redis configuration.
|
||||
type Config struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Db int `json:"db"`
|
||||
Pass string `json:"pass"` // Password for AUTH.
|
||||
MaxIdle int `json:"maxIdle"` // Maximum number of connections allowed to be idle (default is 10)
|
||||
MaxActive int `json:"maxActive"` // Maximum number of connections limit (default is 0 means no limit).
|
||||
IdleTimeout time.Duration `json:"idleTimeout"` // Maximum idle time for connection (default is 10 seconds, not allowed to be set to 0)
|
||||
MaxConnLifetime time.Duration `json:"maxConnLifetime"` // Maximum lifetime of the connection (default is 30 seconds, not allowed to be set to 0)
|
||||
ConnectTimeout time.Duration `json:"connectTimeout"` // Dial connection timeout.
|
||||
TLS bool `json:"tls"` // Specifies the config to use when a TLS connection is dialed.
|
||||
TLSSkipVerify bool `json:"tlsSkipVerify"` // Disables server name verification when connecting over TLS.
|
||||
}
|
||||
|
||||
func New(config ...*Config) (*Redis, error) {
|
||||
if len(config) > 0 {
|
||||
return &Redis{adapter: NewAdapterRedigo(config[0])}, nil
|
||||
@ -58,45 +35,3 @@ func New(config ...*Config) (*Redis, error) {
|
||||
func NewWithAdapter(adapter Adapter) *Redis {
|
||||
return &Redis{adapter: adapter}
|
||||
}
|
||||
|
||||
func (r *Redis) SetAdapter(adapter Adapter) {
|
||||
r.adapter = adapter
|
||||
}
|
||||
|
||||
// Conn returns a raw underlying connection object,
|
||||
// which expose more methods to communicate with server.
|
||||
// **You should call Close function manually if you do not use this connection any further.**
|
||||
func (r *Redis) Conn(ctx context.Context) (Conn, error) {
|
||||
return r.adapter.Conn(ctx)
|
||||
}
|
||||
|
||||
// Stats returns pool's statistics.
|
||||
func (r *Redis) Stats(ctx context.Context) (Stats, error) {
|
||||
return r.adapter.Stats(ctx)
|
||||
}
|
||||
|
||||
// Do sends a command to the server and returns the received reply.
|
||||
// Do automatically get a connection from pool, and close it when the reply received.
|
||||
// It does not really "close" the connection, but drops it back to the connection pool.
|
||||
func (r *Redis) Do(ctx context.Context, command string, args ...interface{}) (*gvar.Var, error) {
|
||||
conn, err := r.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close(ctx)
|
||||
|
||||
if len(args) > 0 {
|
||||
lastElement := args[len(args)-1]
|
||||
switch option := lastElement.(type) {
|
||||
case Option:
|
||||
return conn.Do(ctx, command, args, &option)
|
||||
|
||||
case *Option:
|
||||
return conn.Do(ctx, command, args, option)
|
||||
|
||||
default:
|
||||
return conn.Do(ctx, command, args, nil)
|
||||
}
|
||||
}
|
||||
return conn.Do(ctx, command, args, nil)
|
||||
}
|
||||
|
||||
@ -28,7 +28,6 @@ import (
|
||||
type AdapterRedigo struct {
|
||||
pool *redis.Pool // Underlying connection pool.
|
||||
config *Config // Configuration.
|
||||
group string // Configuration group.
|
||||
}
|
||||
|
||||
const (
|
||||
@ -86,12 +85,12 @@ func NewAdapterRedigo(config *Config) *AdapterRedigo {
|
||||
intlog.Printf(context.TODO(), `open new connection, config:%+v`, config)
|
||||
// AUTH
|
||||
if len(config.Pass) > 0 {
|
||||
if _, err := c.Do("AUTH", config.Pass); err != nil {
|
||||
if _, err = c.Do("AUTH", config.Pass); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// DB
|
||||
if _, err := c.Do("SELECT", config.Db); err != nil {
|
||||
if _, err = c.Do("SELECT", config.Db); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
|
||||
@ -68,7 +68,7 @@ func (c *localAdapterRedisConn) Do(ctx context.Context, command string, args []i
|
||||
// Receive receives a single reply as gvar.Var from the Redis server.
|
||||
func (c *localAdapterRedisConn) Receive(ctx context.Context, option *Option) (*gvar.Var, error) {
|
||||
if option == nil {
|
||||
option = &Option{}
|
||||
option = defaultOption()
|
||||
}
|
||||
return resultToVar(c.ReceiveWithTimeout(option.ReadTimeout))
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
@ -18,6 +19,21 @@ import (
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
// Config is redis configuration.
|
||||
type Config struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Db int `json:"db"`
|
||||
Pass string `json:"pass"` // Password for AUTH.
|
||||
MaxIdle int `json:"maxIdle"` // Maximum number of connections allowed to be idle (default is 10)
|
||||
MaxActive int `json:"maxActive"` // Maximum number of connections limit (default is 0 means no limit).
|
||||
IdleTimeout time.Duration `json:"idleTimeout"` // Maximum idle time for connection (default is 10 seconds, not allowed to be set to 0)
|
||||
MaxConnLifetime time.Duration `json:"maxConnLifetime"` // Maximum lifetime of the connection (default is 30 seconds, not allowed to be set to 0)
|
||||
ConnectTimeout time.Duration `json:"connectTimeout"` // Dial connection timeout.
|
||||
TLS bool `json:"tls"` // Specifies the config to use when a TLS connection is dialed.
|
||||
TLSSkipVerify bool `json:"tlsSkipVerify"` // Disables server name verification when connecting over TLS.
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultGroupName = "default" // Default configuration group name.
|
||||
DefaultRedisPort = 6379 // Default redis port configuration if not passed.
|
||||
|
||||
@ -6,7 +6,11 @@
|
||||
|
||||
package gredis
|
||||
|
||||
import "github.com/gogf/gf/container/gmap"
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
)
|
||||
|
||||
var (
|
||||
// Instance map
|
||||
@ -23,8 +27,11 @@ func Instance(name ...string) *Redis {
|
||||
}
|
||||
v := instances.GetOrSetFuncLock(group, func() interface{} {
|
||||
if config, ok := GetConfig(group); ok {
|
||||
r := NewAdapterRedigo(config)
|
||||
r.group = group
|
||||
r, err := New(config)
|
||||
if err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
return nil
|
||||
}
|
||||
return r
|
||||
}
|
||||
return nil
|
||||
|
||||
86
database/gredis/gredis_redis.go
Normal file
86
database/gredis/gredis_redis.go
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gredis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/container/gvar"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
)
|
||||
|
||||
// Redis client.
|
||||
type Redis struct {
|
||||
adapter Adapter
|
||||
}
|
||||
|
||||
const (
|
||||
errorNilRedis = `the Redis object is nil`
|
||||
)
|
||||
|
||||
func (r *Redis) SetAdapter(adapter Adapter) {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
r.adapter = adapter
|
||||
}
|
||||
|
||||
func (r *Redis) GetAdapter() Adapter {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return r.adapter
|
||||
}
|
||||
|
||||
// Conn returns a raw underlying connection object,
|
||||
// which expose more methods to communicate with server.
|
||||
// **You should call Close function manually if you do not use this connection any further.**
|
||||
func (r *Redis) Conn(ctx context.Context) (*RedisConn, error) {
|
||||
if r == nil {
|
||||
return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis)
|
||||
}
|
||||
conn, err := r.adapter.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RedisConn{conn: conn}, nil
|
||||
}
|
||||
|
||||
// Stats returns pool's statistics.
|
||||
func (r *Redis) Stats(ctx context.Context) (Stats, error) {
|
||||
if r == nil {
|
||||
return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis)
|
||||
}
|
||||
return r.adapter.Stats(ctx)
|
||||
}
|
||||
|
||||
// Do sends a command to the server and returns the received reply.
|
||||
// Do automatically get a connection from pool, and close it when the reply received.
|
||||
// It does not really "close" the connection, but drops it back to the connection pool.
|
||||
func (r *Redis) Do(ctx context.Context, command string, args ...interface{}) (*gvar.Var, error) {
|
||||
if r == nil {
|
||||
return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis)
|
||||
}
|
||||
conn, err := r.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := conn.Close(ctx); err != nil {
|
||||
intlog.Error(ctx, err)
|
||||
}
|
||||
}()
|
||||
return conn.Do(ctx, command, args...)
|
||||
}
|
||||
|
||||
func (r *Redis) Close(ctx context.Context) error {
|
||||
if r == nil {
|
||||
return gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis)
|
||||
}
|
||||
return r.adapter.Close(ctx)
|
||||
}
|
||||
38
database/gredis/gredis_redis_conn.go
Normal file
38
database/gredis/gredis_redis_conn.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gredis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/container/gvar"
|
||||
)
|
||||
|
||||
type RedisConn struct {
|
||||
conn Conn
|
||||
}
|
||||
|
||||
func (c *RedisConn) Do(ctx context.Context, command string, args ...interface{}) (reply *gvar.Var, err error) {
|
||||
args, option := parseArgsToArgsAndOption(args)
|
||||
return c.conn.Do(ctx, command, args, option)
|
||||
}
|
||||
|
||||
// Receive receives a single reply as gvar.Var from the Redis server.
|
||||
func (c *RedisConn) Receive(ctx context.Context, option ...*Option) (*gvar.Var, error) {
|
||||
var (
|
||||
usedOption *Option
|
||||
)
|
||||
if len(option) > 0 {
|
||||
usedOption = option[0]
|
||||
} else {
|
||||
usedOption = defaultOption()
|
||||
}
|
||||
return c.conn.Receive(ctx, usedOption)
|
||||
}
|
||||
|
||||
func (c *RedisConn) Close(ctx context.Context) error {
|
||||
return c.conn.Close(ctx)
|
||||
}
|
||||
25
database/gredis/gredis_utils.go
Normal file
25
database/gredis/gredis_utils.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gredis
|
||||
|
||||
func defaultOption() *Option {
|
||||
return &Option{}
|
||||
}
|
||||
|
||||
func parseArgsToArgsAndOption(arguments []interface{}) (args []interface{}, option *Option) {
|
||||
if length := len(arguments); length > 0 {
|
||||
lastElement := arguments[length-1]
|
||||
switch result := lastElement.(type) {
|
||||
case Option:
|
||||
return arguments[:length-1], &result
|
||||
|
||||
case *Option:
|
||||
return arguments[:length-1], result
|
||||
}
|
||||
}
|
||||
return arguments, defaultOption()
|
||||
}
|
||||
@ -22,37 +22,42 @@ func TestConn_DoWithTimeout(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNil(redis)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
defer conn.Close(ctx)
|
||||
|
||||
_, err := conn.Do(ctx, "set", "test", "123", &gredis.Option{ReadTimeout: time.Second})
|
||||
_, err = conn.Do(ctx, "set", "test", "123", &gredis.Option{ReadTimeout: time.Second})
|
||||
t.Assert(err, nil)
|
||||
defer conn.DoWithTimeout(time.Second, "del", "test")
|
||||
defer conn.Do(ctx, "del", "test")
|
||||
|
||||
r, err := conn.DoWithTimeout(time.Second, "get", "test")
|
||||
r, err := conn.Do(ctx, "get", "test", &gredis.Option{ReadTimeout: time.Second})
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, "123")
|
||||
t.Assert(r.String(), "123")
|
||||
})
|
||||
}
|
||||
|
||||
func TestConn_ReceiveVarWithTimeout(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
conn := redis.Conn()
|
||||
defer conn.Close()
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err := conn.DoVarWithTimeout(time.Second, "Subscribe", "gf")
|
||||
t.Assert(err, nil)
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
defer conn.Close(ctx)
|
||||
|
||||
v, err := redis.DoVarWithTimeout(time.Second, "PUBLISH", "gf", "test")
|
||||
_, err = conn.Do(ctx, "Subscribe", "gf", &gredis.Option{ReadTimeout: time.Second})
|
||||
t.AssertNil(err)
|
||||
|
||||
v, err := redis.Do(ctx, "PUBLISH", "gf", "test", &gredis.Option{ReadTimeout: time.Second})
|
||||
t.Assert(err, nil)
|
||||
t.Assert(v.String(), "1")
|
||||
|
||||
v, _ = conn.ReceiveVar()
|
||||
v, _ = conn.Receive(ctx)
|
||||
t.Assert(len(v.Strings()), 3)
|
||||
t.Assert(v.Strings()[2], "test")
|
||||
})
|
||||
|
||||
@ -31,27 +31,32 @@ var (
|
||||
|
||||
func Test_NewClose(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
err := redis.Close()
|
||||
t.Assert(err, nil)
|
||||
|
||||
err = redis.Close(ctx)
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Do(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
defer redis.Close()
|
||||
_, err := redis.Do("SET", "k", "v")
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err = redis.Do(ctx, "SET", "k", "v")
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.Do("GET", "k")
|
||||
r, err := redis.Do(ctx, "GET", "k")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, []byte("v"))
|
||||
|
||||
_, err = redis.Do("DEL", "k")
|
||||
_, err = redis.Do(ctx, "DEL", "k")
|
||||
t.Assert(err, nil)
|
||||
r, err = redis.Do("GET", "k")
|
||||
r, err = redis.Do(ctx, "GET", "k")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, nil)
|
||||
})
|
||||
@ -59,26 +64,30 @@ func Test_Do(t *testing.T) {
|
||||
|
||||
func Test_Stats(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
defer redis.Close()
|
||||
redis.SetMaxIdle(2)
|
||||
redis.SetMaxActive(100)
|
||||
redis.SetIdleTimeout(500 * time.Millisecond)
|
||||
redis.SetMaxConnLifetime(500 * time.Millisecond)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
array := make([]*gredis.Conn, 0)
|
||||
array := make([]*gredis.RedisConn, 0)
|
||||
for i := 0; i < 10; i++ {
|
||||
array = append(array, redis.Conn())
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
array = append(array, conn)
|
||||
}
|
||||
stats := redis.Stats()
|
||||
t.Assert(stats.ActiveCount, 10)
|
||||
t.Assert(stats.IdleCount, 0)
|
||||
stats, err := redis.Stats(ctx)
|
||||
t.AssertNil(err)
|
||||
t.Assert(stats.ActiveCount(), 10)
|
||||
t.Assert(stats.IdleCount(), 0)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
array[i].Close()
|
||||
t.AssertNil(array[i].Close(ctx))
|
||||
}
|
||||
stats = redis.Stats()
|
||||
t.Assert(stats.ActiveCount, 2)
|
||||
t.Assert(stats.IdleCount, 2)
|
||||
|
||||
stats, err = redis.Stats(ctx)
|
||||
t.AssertNil(err)
|
||||
t.Assert(stats.ActiveCount(), 10)
|
||||
t.Assert(stats.IdleCount(), 10)
|
||||
//time.Sleep(3000*time.Millisecond)
|
||||
//stats = redis.Stats()
|
||||
//fmt.Println(stats)
|
||||
@ -89,23 +98,27 @@ func Test_Stats(t *testing.T) {
|
||||
|
||||
func Test_Conn(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
defer redis.Close()
|
||||
conn := redis.Conn()
|
||||
defer conn.Close()
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
defer conn.Close(ctx)
|
||||
|
||||
key := gconv.String(gtime.TimestampNano())
|
||||
value := []byte("v")
|
||||
r, err := conn.Do("SET", key, value)
|
||||
r, err := conn.Do(ctx, "SET", key, value)
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err = conn.Do("GET", key)
|
||||
r, err = conn.Do(ctx, "GET", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, value)
|
||||
|
||||
_, err = conn.Do("DEL", key)
|
||||
_, err = conn.Do(ctx, "DEL", key)
|
||||
t.Assert(err, nil)
|
||||
r, err = conn.Do("GET", key)
|
||||
r, err = conn.Do(ctx, "GET", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, nil)
|
||||
})
|
||||
@ -116,22 +129,24 @@ func Test_Instance(t *testing.T) {
|
||||
group := "my-test"
|
||||
gredis.SetConfig(config, group)
|
||||
defer gredis.RemoveConfig(group)
|
||||
|
||||
redis := gredis.Instance(group)
|
||||
defer redis.Close()
|
||||
defer redis.Close(ctx)
|
||||
|
||||
conn := redis.Conn()
|
||||
defer conn.Close()
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
defer conn.Close(ctx)
|
||||
|
||||
_, err := conn.Do("SET", "k", "v")
|
||||
_, err = conn.Do(ctx, "SET", "k", "v")
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := conn.Do("GET", "k")
|
||||
r, err := conn.Do(ctx, "GET", "k")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, []byte("v"))
|
||||
|
||||
_, err = conn.Do("DEL", "k")
|
||||
_, err = conn.Do(ctx, "DEL", "k")
|
||||
t.Assert(err, nil)
|
||||
r, err = conn.Do("GET", "k")
|
||||
r, err = conn.Do(ctx, "GET", "k")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r, nil)
|
||||
})
|
||||
@ -145,8 +160,12 @@ func Test_Error(t *testing.T) {
|
||||
Db: 1,
|
||||
ConnectTimeout: time.Second,
|
||||
}
|
||||
redis := gredis.New(config1)
|
||||
_, err := redis.Do("info")
|
||||
redis, err := gredis.New(config1)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err = redis.Do(ctx, "info")
|
||||
t.AssertNE(err, nil)
|
||||
|
||||
config1 = &gredis.Config{
|
||||
@ -154,35 +173,43 @@ func Test_Error(t *testing.T) {
|
||||
Port: 6379,
|
||||
Db: 100,
|
||||
}
|
||||
redis = gredis.New(config1)
|
||||
_, err = redis.Do("info")
|
||||
redis, err = gredis.New(config1)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err = redis.Do(ctx, "info")
|
||||
t.AssertNE(err, nil)
|
||||
|
||||
redis = gredis.Instance("gf")
|
||||
t.Assert(redis == nil, true)
|
||||
gredis.ClearConfig()
|
||||
|
||||
redis = gredis.New(config)
|
||||
defer redis.Close()
|
||||
_, err = redis.DoVar("SET", "k", "v")
|
||||
redis, err = gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err = redis.Do(ctx, "SET", "k", "v")
|
||||
t.Assert(err, nil)
|
||||
|
||||
v, err := redis.DoVar("GET", "k")
|
||||
v, err := redis.Do(ctx, "GET", "k")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(v.String(), "v")
|
||||
|
||||
conn := redis.Conn()
|
||||
defer conn.Close()
|
||||
_, err = conn.DoVar("SET", "k", "v")
|
||||
conn, err := redis.Conn(ctx)
|
||||
t.AssertNil(err)
|
||||
defer conn.Close(ctx)
|
||||
_, err = conn.Do(ctx, "SET", "k", "v")
|
||||
t.Assert(err, nil)
|
||||
|
||||
_, err = conn.DoVar("Subscribe", "gf")
|
||||
_, err = conn.Do(ctx, "Subscribe", "gf")
|
||||
t.Assert(err, nil)
|
||||
|
||||
_, err = redis.DoVar("PUBLISH", "gf", "test")
|
||||
_, err = redis.Do(ctx, "PUBLISH", "gf", "test")
|
||||
t.Assert(err, nil)
|
||||
|
||||
v, _ = conn.ReceiveVar()
|
||||
v, _ = conn.Receive(ctx)
|
||||
t.Assert(len(v.Strings()), 3)
|
||||
t.Assert(v.Strings()[2], "test")
|
||||
|
||||
@ -192,23 +219,27 @@ func Test_Error(t *testing.T) {
|
||||
|
||||
func Test_Bool(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
defer func() {
|
||||
redis.Do("DEL", "key-true")
|
||||
redis.Do("DEL", "key-false")
|
||||
redis.Do(ctx, "DEL", "key-true")
|
||||
redis.Do(ctx, "DEL", "key-false")
|
||||
}()
|
||||
|
||||
_, err := redis.Do("SET", "key-true", true)
|
||||
_, err = redis.Do(ctx, "SET", "key-true", true)
|
||||
t.Assert(err, nil)
|
||||
|
||||
_, err = redis.Do("SET", "key-false", false)
|
||||
_, err = redis.Do(ctx, "SET", "key-false", false)
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.DoVar("GET", "key-true")
|
||||
r, err := redis.Do(ctx, "GET", "key-true")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Bool(), true)
|
||||
|
||||
r, err = redis.DoVar("GET", "key-false")
|
||||
r, err = redis.Do(ctx, "GET", "key-false")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Bool(), false)
|
||||
})
|
||||
@ -216,14 +247,18 @@ func Test_Bool(t *testing.T) {
|
||||
|
||||
func Test_Int(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
key := guid.S()
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err := redis.Do("SET", key, 1)
|
||||
key := guid.S()
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do(ctx, "SET", key, 1)
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.DoVar("GET", key)
|
||||
r, err := redis.Do(ctx, "GET", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Int(), 1)
|
||||
})
|
||||
@ -231,14 +266,18 @@ func Test_Int(t *testing.T) {
|
||||
|
||||
func Test_HSet(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
redis := gredis.New(config)
|
||||
key := guid.S()
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
_, err := redis.Do("HSET", key, "name", "john")
|
||||
key := guid.S()
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do(ctx, "HSET", key, "name", "john")
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.DoVar("HGETALL", key)
|
||||
r, err := redis.Do(ctx, "HGETALL", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Strings(), g.ArrayStr{"name", "john"})
|
||||
})
|
||||
@ -247,18 +286,20 @@ func Test_HSet(t *testing.T) {
|
||||
func Test_HGetAll1(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
key = guid.S()
|
||||
redis = gredis.New(config)
|
||||
key = guid.S()
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do("HSET", key, "id", 100)
|
||||
_, err = redis.Do(ctx, "HSET", key, "id", 100)
|
||||
t.Assert(err, nil)
|
||||
_, err = redis.Do("HSET", key, "name", "john")
|
||||
_, err = redis.Do(ctx, "HSET", key, "name", "john")
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.DoVar("HGETALL", key)
|
||||
r, err := redis.Do(ctx, "HGETALL", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Map(), g.MapStrAny{
|
||||
"id": 100,
|
||||
@ -270,18 +311,20 @@ func Test_HGetAll1(t *testing.T) {
|
||||
func Test_HGetAll2(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
key = guid.S()
|
||||
redis = gredis.New(config)
|
||||
key = guid.S()
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do("HSET", key, "id", 100)
|
||||
_, err = redis.Do(ctx, "HSET", key, "id", 100)
|
||||
t.Assert(err, nil)
|
||||
_, err = redis.Do("HSET", key, "name", "john")
|
||||
_, err = redis.Do(ctx, "HSET", key, "name", "john")
|
||||
t.Assert(err, nil)
|
||||
|
||||
result, err := redis.DoVar("HGETALL", key)
|
||||
result, err := redis.Do(ctx, "HGETALL", key)
|
||||
t.Assert(err, nil)
|
||||
|
||||
t.Assert(gconv.Uint(result.MapStrVar()["id"]), 100)
|
||||
@ -293,20 +336,22 @@ func Test_HMSet(t *testing.T) {
|
||||
// map
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
key = guid.S()
|
||||
redis = gredis.New(config)
|
||||
data = g.Map{
|
||||
key = guid.S()
|
||||
data = g.Map{
|
||||
"name": "gf",
|
||||
"sex": 0,
|
||||
"score": 100,
|
||||
}
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do("HMSET", append(g.Slice{key}, gutil.MapToSlice(data)...)...)
|
||||
_, err = redis.Do(ctx, "HMSET", append(g.Slice{key}, gutil.MapToSlice(data)...)...)
|
||||
t.Assert(err, nil)
|
||||
v, err := redis.DoVar("HMGET", key, "name")
|
||||
v, err := redis.Do(ctx, "HMGET", key, "name")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(v.Slice(), g.Slice{data["name"]})
|
||||
})
|
||||
@ -318,48 +363,53 @@ func Test_HMSet(t *testing.T) {
|
||||
Score int `json:"score"`
|
||||
}
|
||||
var (
|
||||
err error
|
||||
key = guid.S()
|
||||
redis = gredis.New(config)
|
||||
data = &User{
|
||||
key = guid.S()
|
||||
data = &User{
|
||||
Name: "gf",
|
||||
Sex: 0,
|
||||
Score: 100,
|
||||
}
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
_, err = redis.Do("HMSET", append(g.Slice{key}, gutil.StructToSlice(data)...)...)
|
||||
_, err = redis.Do(ctx, "HMSET", append(g.Slice{key}, gutil.StructToSlice(data)...)...)
|
||||
t.Assert(err, nil)
|
||||
v, err := redis.DoVar("HMGET", key, "name")
|
||||
v, err := redis.Do(ctx, "HMGET", key, "name")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(v.Slice(), g.Slice{data.Name})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Auto_Marshal(t *testing.T) {
|
||||
var (
|
||||
err error
|
||||
redis = gredis.New(config)
|
||||
key = guid.S()
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
|
||||
type User struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
key = guid.S()
|
||||
)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Close(ctx)
|
||||
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
|
||||
type User struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
|
||||
user := &User{
|
||||
Id: 10000,
|
||||
Name: "john",
|
||||
}
|
||||
|
||||
_, err = redis.Do("SET", key, user)
|
||||
_, err = redis.Do(ctx, "SET", key, user)
|
||||
t.Assert(err, nil)
|
||||
|
||||
r, err := redis.DoVar("GET", key)
|
||||
r, err := redis.Do(ctx, "GET", key)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(r.Map(), g.MapStrAny{
|
||||
"Id": user.Id,
|
||||
@ -374,22 +424,20 @@ func Test_Auto_Marshal(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_Auto_MarshalSlice(t *testing.T) {
|
||||
var (
|
||||
err error
|
||||
redis = gredis.New(config)
|
||||
key = guid.S()
|
||||
)
|
||||
defer redis.Do("DEL", key)
|
||||
|
||||
type User struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
key = "user-slice"
|
||||
)
|
||||
redis, err := gredis.New(config)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(redis, nil)
|
||||
defer redis.Do(ctx, "DEL", key)
|
||||
type User struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
var (
|
||||
result *gvar.Var
|
||||
key = "user-slice"
|
||||
users1 = []User{
|
||||
{
|
||||
Id: 1,
|
||||
@ -402,10 +450,10 @@ func Test_Auto_MarshalSlice(t *testing.T) {
|
||||
}
|
||||
)
|
||||
|
||||
_, err = redis.Do("SET", key, users1)
|
||||
_, err = redis.Do(ctx, "SET", key, users1)
|
||||
t.Assert(err, nil)
|
||||
|
||||
result, err = redis.DoVar("GET", key)
|
||||
result, err = redis.Do(ctx, "GET", key)
|
||||
t.Assert(err, nil)
|
||||
|
||||
var users2 []User
|
||||
|
||||
@ -239,7 +239,7 @@ func (s *Session) Size() int {
|
||||
// Contains checks whether key exist in the session.
|
||||
func (s *Session) Contains(key string) bool {
|
||||
s.init()
|
||||
return s.Get(key) != nil
|
||||
return !s.Get(key).IsNil()
|
||||
}
|
||||
|
||||
// IsDirty checks whether there's any data changes in the session.
|
||||
|
||||
@ -46,21 +46,24 @@ func (s *StorageRedisHashTable) New(ctx context.Context, ttl time.Duration) (id
|
||||
// Get retrieves session value with given key.
|
||||
// It returns nil if the key does not exist in the session.
|
||||
func (s *StorageRedisHashTable) Get(ctx context.Context, id string, key string) (value interface{}, err error) {
|
||||
value, err = s.redis.Do(ctx, "HGET", s.key(id), key)
|
||||
if value != nil {
|
||||
value = gconv.String(value)
|
||||
v, err := s.redis.Do(ctx, "HGET", s.key(id), key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
if v.IsNil() {
|
||||
return nil, nil
|
||||
}
|
||||
return v.String(), nil
|
||||
}
|
||||
|
||||
// GetMap retrieves all key-value pairs as map from storage.
|
||||
func (s *StorageRedisHashTable) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) {
|
||||
r, err := s.redis.Do(ctx, "HGETALL", s.key(id))
|
||||
v, err := s.redis.Do(ctx, "HGETALL", s.key(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = make(map[string]interface{})
|
||||
array := r.Interfaces()
|
||||
array := v.Interfaces()
|
||||
for i := 0; i < len(array); i += 2 {
|
||||
if array[i+1] != nil {
|
||||
data[gconv.String(array[i])] = gconv.String(array[i+1])
|
||||
|
||||
@ -18,9 +18,10 @@ import (
|
||||
)
|
||||
|
||||
func Test_StorageRedisHashTable(t *testing.T) {
|
||||
redis, err := gredis.NewFromStr("127.0.0.1:6379,0")
|
||||
config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0")
|
||||
redis, err := gredis.New(config)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
})
|
||||
|
||||
storage := gsession.NewStorageRedisHashTable(redis)
|
||||
@ -80,7 +81,8 @@ func Test_StorageRedisHashTable(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_StorageRedisHashTablePrefix(t *testing.T) {
|
||||
redis, err := gredis.NewFromStr("127.0.0.1:6379,0")
|
||||
config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0")
|
||||
redis, err := gredis.New(config)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
t.Assert(err, nil)
|
||||
})
|
||||
|
||||
@ -18,7 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func Test_StorageRedis(t *testing.T) {
|
||||
redis, err := gredis.NewFromStr("127.0.0.1:6379,0")
|
||||
config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0")
|
||||
redis, err := gredis.New(config)
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
storage := gsession.NewStorageRedis(redis)
|
||||
@ -79,7 +80,8 @@ func Test_StorageRedis(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_StorageRedisPrefix(t *testing.T) {
|
||||
redis, err := gredis.NewFromStr("127.0.0.1:6379,0")
|
||||
config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0")
|
||||
redis, err := gredis.New(config)
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
prefix := "s_"
|
||||
|
||||
Reference in New Issue
Block a user