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  }