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 }