github.com/aaabigfish/gopkg@v1.1.0/database/redis/redis.go (about) 1 package redis 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/url" 8 "reflect" 9 "strconv" 10 "strings" 11 "time" 12 13 gredis "github.com/redis/go-redis/v9" 14 ) 15 16 // Client redis 客户端 17 type Client struct { 18 gredis.UniversalClient 19 } 20 21 // Get 获取缓存实例 22 func NewClient(dsn string) *Client { 23 opts := &gredis.UniversalOptions{} 24 25 setOptions(opts, dsn) 26 27 rdb := gredis.NewUniversalClient(opts) 28 29 db := &Client{rdb} 30 31 return db 32 33 } 34 35 func setOptions(opts *gredis.UniversalOptions, dsn string) { 36 url, err := url.Parse(dsn) 37 if err != nil { 38 panic(err) 39 } 40 41 args := url.Query() 42 43 rv := reflect.ValueOf(opts).Elem() 44 rt := rv.Type() 45 46 for i := 0; i < rv.NumField(); i++ { 47 f := rv.Field(i) 48 if !f.CanInterface() { 49 continue 50 } 51 name := rt.Field(i).Name 52 arg := args.Get(name) 53 if arg == "" { 54 continue 55 } 56 switch f.Interface().(type) { 57 case time.Duration: 58 v, err := time.ParseDuration(arg) 59 if err != nil { 60 panic(fmt.Sprintf("%s=%s, err:%v", name, arg, err)) 61 } 62 f.Set(reflect.ValueOf(v)) 63 case int: 64 v, err := strconv.Atoi(arg) 65 if err != nil { 66 panic(fmt.Sprintf("%s=%s, err:%v", name, arg, err)) 67 } 68 f.SetInt(int64(v)) 69 case bool: 70 v, err := strconv.ParseBool(arg) 71 if err != nil { 72 panic(fmt.Sprintf("%s=%s, err:%v", name, arg, err)) 73 } 74 f.SetBool(v) 75 case string: 76 f.SetString(arg) 77 } 78 } 79 80 opts.Addrs = []string{url.Host} 81 opts.Username = url.User.Username() 82 if p, ok := url.User.Password(); ok { 83 opts.Password = p 84 } 85 86 // 获取database 87 f := strings.FieldsFunc(url.Path, func(r rune) bool { 88 return r == '/' 89 }) 90 switch len(f) { 91 case 0: 92 opts.DB = 0 93 case 1: 94 var err error 95 if opts.DB, err = strconv.Atoi(f[0]); err != nil { 96 panic(fmt.Sprintf("redis: invalid database number: %q", f[0])) 97 } 98 default: 99 panic(fmt.Sprintf("redis: invalid URL path: %s", url.Path)) 100 } 101 } 102 103 func (c *Client) SaveStruct(ctx context.Context, key string, data interface{}, second int) error { 104 bData, err := json.Marshal(data) 105 if err != nil { 106 return fmt.Errorf("save key(%s) json.Marshal(%v) err(%v)", key, data, err) 107 } 108 err = c.Set(ctx, key, string(bData), time.Duration(second)*time.Second).Err() 109 if err != nil { 110 return fmt.Errorf("save key(%s) fail:%s", key, err.Error()) 111 } 112 return nil 113 } 114 115 func (c *Client) GetStruct(ctx context.Context, key string, data interface{}) error { 116 valStr, err := c.Get(ctx, key).Result() 117 if gredis.Nil == err { 118 return fmt.Errorf("key(%s) not found", key) 119 } 120 if err != nil { 121 return fmt.Errorf("get key(%s) fail:%s", key, err.Error()) 122 } 123 return json.Unmarshal([]byte(valStr), &data) 124 }