github.com/zooyer/miskit@v1.0.71/imdb/driver/redis/redis.go (about)

     1  package redis
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/go-redis/redis"
    11  	"github.com/zooyer/miskit/imdb"
    12  )
    13  
    14  type redisConn struct {
    15  	rds *redis.Client
    16  }
    17  
    18  type redisDriver int
    19  
    20  func (r redisDriver) parseDuration(str string) (duration time.Duration, err error) {
    21  	if len(str) < 2 {
    22  		return 0, fmt.Errorf("duration error")
    23  	}
    24  
    25  	var index = 0
    26  	for ; index < len(str); index++ {
    27  		if str[index] < '0' || str[index] > '9' {
    28  			break
    29  		}
    30  	}
    31  
    32  	var unit = str[index:]
    33  	i, err := strconv.Atoi(str[:index])
    34  	if err != nil {
    35  		return
    36  	}
    37  
    38  	switch unit {
    39  	case "ms":
    40  		return time.Duration(i) * time.Millisecond, nil
    41  	case "s":
    42  		return time.Duration(i) * time.Second, nil
    43  	case "min":
    44  		return time.Duration(i) * time.Minute, nil
    45  	case "h":
    46  		return time.Duration(i) * time.Hour, nil
    47  	}
    48  
    49  	return 0, fmt.Errorf("unknown time unit: %s", unit)
    50  }
    51  
    52  func (r redisDriver) parseArgs(args string) (opts *redis.Options, err error) {
    53  	var options = redis.Options{
    54  		Addr:         "localhost",
    55  		ReadTimeout:  time.Second * 5,
    56  		WriteTimeout: time.Second * 5,
    57  	}
    58  
    59  	var fields = strings.SplitN(args, "?", 2)
    60  
    61  	var endpoint = strings.Split(fields[0], "/")
    62  	if len(endpoint) > 0 && endpoint[0] != "" {
    63  		options.Addr = endpoint[0]
    64  		if len(endpoint) > 1 && endpoint[1] != "" {
    65  			if options.DB, err = strconv.Atoi(endpoint[1]); err != nil {
    66  				return
    67  			}
    68  		}
    69  	}
    70  
    71  	if len(fields) > 1 && fields[1] != "" {
    72  		var params = strings.Split(fields[1], "&")
    73  		for _, param := range params {
    74  			if param == "" {
    75  				continue
    76  			}
    77  
    78  			var kv = strings.SplitN(param, "=", 2)
    79  			if len(kv) < 2 || kv[1] == "" {
    80  				continue
    81  			}
    82  
    83  			switch kv[0] {
    84  			case "password", "Password":
    85  				options.Password = kv[1]
    86  			case "dial_timeout", "dialTimeout", "DialTimeout":
    87  				if options.DialTimeout, err = r.parseDuration(kv[1]); err != nil {
    88  					return
    89  				}
    90  			case "read_timeout", "readTimeout", "ReadTimeout":
    91  				if options.ReadTimeout, err = r.parseDuration(kv[1]); err != nil {
    92  					return
    93  				}
    94  			case "write_timeout", "writeTimeout", "WriteTimeout":
    95  				if options.WriteTimeout, err = r.parseDuration(kv[1]); err != nil {
    96  					return
    97  				}
    98  			case "pool_size", "poolSize", "PoolSize":
    99  				if options.PoolSize, err = strconv.Atoi(kv[1]); err != nil {
   100  					return
   101  				}
   102  			}
   103  		}
   104  	}
   105  
   106  	return &options, nil
   107  }
   108  
   109  func (r redisDriver) Open(args string) (conn imdb.Conn, err error) {
   110  	var c redisConn
   111  
   112  	opts, err := r.parseArgs(args)
   113  	if err != nil {
   114  		return
   115  	}
   116  
   117  	c.rds = redis.NewClient(opts)
   118  
   119  	if _, err = c.rds.Ping().Result(); err != nil {
   120  		return
   121  	}
   122  
   123  	return &c, nil
   124  }
   125  
   126  func (c redisConn) Get(ctx context.Context, key string) (value string, err error) {
   127  	if value, err = c.rds.Get(key).Result(); err != nil {
   128  		if err == redis.Nil {
   129  			err = nil
   130  		}
   131  	}
   132  
   133  	return
   134  }
   135  
   136  func (c redisConn) Set(ctx context.Context, key, value string) (err error) {
   137  	if _, err = c.rds.Set(key, value, 0).Result(); err != nil {
   138  		return
   139  	}
   140  
   141  	return
   142  }
   143  
   144  func (c redisConn) SetEx(ctx context.Context, key, value string, seconds int64) (err error) {
   145  	if _, err = c.rds.Set(key, value, time.Second*time.Duration(seconds)).Result(); err != nil {
   146  		return
   147  	}
   148  
   149  	return
   150  }
   151  
   152  func (c redisConn) Del(ctx context.Context, key string) (err error) {
   153  	if _, err = c.rds.Del(key).Result(); err != nil {
   154  		return
   155  	}
   156  
   157  	return
   158  }
   159  
   160  func (c redisConn) TTL(ctx context.Context, key string) (seconds int64, err error) {
   161  	ttl, err := c.rds.TTL(key).Result()
   162  	if err != nil {
   163  		return
   164  	}
   165  
   166  	return int64(ttl.Seconds()), nil
   167  }
   168  
   169  func init() {
   170  	imdb.Register("redis", new(redisDriver))
   171  }