github.com/astaxie/beego@v1.12.3/cache/ssdb/ssdb.go (about) 1 package ssdb 2 3 import ( 4 "encoding/json" 5 "errors" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/ssdb/gossdb/ssdb" 11 12 "github.com/astaxie/beego/cache" 13 ) 14 15 // Cache SSDB adapter 16 type Cache struct { 17 conn *ssdb.Client 18 conninfo []string 19 } 20 21 //NewSsdbCache create new ssdb adapter. 22 func NewSsdbCache() cache.Cache { 23 return &Cache{} 24 } 25 26 // Get get value from memcache. 27 func (rc *Cache) Get(key string) interface{} { 28 if rc.conn == nil { 29 if err := rc.connectInit(); err != nil { 30 return nil 31 } 32 } 33 value, err := rc.conn.Get(key) 34 if err == nil { 35 return value 36 } 37 return nil 38 } 39 40 // GetMulti get value from memcache. 41 func (rc *Cache) GetMulti(keys []string) []interface{} { 42 size := len(keys) 43 var values []interface{} 44 if rc.conn == nil { 45 if err := rc.connectInit(); err != nil { 46 for i := 0; i < size; i++ { 47 values = append(values, err) 48 } 49 return values 50 } 51 } 52 res, err := rc.conn.Do("multi_get", keys) 53 resSize := len(res) 54 if err == nil { 55 for i := 1; i < resSize; i += 2 { 56 values = append(values, res[i+1]) 57 } 58 return values 59 } 60 for i := 0; i < size; i++ { 61 values = append(values, err) 62 } 63 return values 64 } 65 66 // DelMulti get value from memcache. 67 func (rc *Cache) DelMulti(keys []string) error { 68 if rc.conn == nil { 69 if err := rc.connectInit(); err != nil { 70 return err 71 } 72 } 73 _, err := rc.conn.Do("multi_del", keys) 74 return err 75 } 76 77 // Put put value to memcache. only support string. 78 func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error { 79 if rc.conn == nil { 80 if err := rc.connectInit(); err != nil { 81 return err 82 } 83 } 84 v, ok := value.(string) 85 if !ok { 86 return errors.New("value must string") 87 } 88 var resp []string 89 var err error 90 ttl := int(timeout / time.Second) 91 if ttl < 0 { 92 resp, err = rc.conn.Do("set", key, v) 93 } else { 94 resp, err = rc.conn.Do("setx", key, v, ttl) 95 } 96 if err != nil { 97 return err 98 } 99 if len(resp) == 2 && resp[0] == "ok" { 100 return nil 101 } 102 return errors.New("bad response") 103 } 104 105 // Delete delete value in memcache. 106 func (rc *Cache) Delete(key string) error { 107 if rc.conn == nil { 108 if err := rc.connectInit(); err != nil { 109 return err 110 } 111 } 112 _, err := rc.conn.Del(key) 113 return err 114 } 115 116 // Incr increase counter. 117 func (rc *Cache) Incr(key string) error { 118 if rc.conn == nil { 119 if err := rc.connectInit(); err != nil { 120 return err 121 } 122 } 123 _, err := rc.conn.Do("incr", key, 1) 124 return err 125 } 126 127 // Decr decrease counter. 128 func (rc *Cache) Decr(key string) error { 129 if rc.conn == nil { 130 if err := rc.connectInit(); err != nil { 131 return err 132 } 133 } 134 _, err := rc.conn.Do("incr", key, -1) 135 return err 136 } 137 138 // IsExist check value exists in memcache. 139 func (rc *Cache) IsExist(key string) bool { 140 if rc.conn == nil { 141 if err := rc.connectInit(); err != nil { 142 return false 143 } 144 } 145 resp, err := rc.conn.Do("exists", key) 146 if err != nil { 147 return false 148 } 149 if len(resp) == 2 && resp[1] == "1" { 150 return true 151 } 152 return false 153 154 } 155 156 // ClearAll clear all cached in memcache. 157 func (rc *Cache) ClearAll() error { 158 if rc.conn == nil { 159 if err := rc.connectInit(); err != nil { 160 return err 161 } 162 } 163 keyStart, keyEnd, limit := "", "", 50 164 resp, err := rc.Scan(keyStart, keyEnd, limit) 165 for err == nil { 166 size := len(resp) 167 if size == 1 { 168 return nil 169 } 170 keys := []string{} 171 for i := 1; i < size; i += 2 { 172 keys = append(keys, resp[i]) 173 } 174 _, e := rc.conn.Do("multi_del", keys) 175 if e != nil { 176 return e 177 } 178 keyStart = resp[size-2] 179 resp, err = rc.Scan(keyStart, keyEnd, limit) 180 } 181 return err 182 } 183 184 // Scan key all cached in ssdb. 185 func (rc *Cache) Scan(keyStart string, keyEnd string, limit int) ([]string, error) { 186 if rc.conn == nil { 187 if err := rc.connectInit(); err != nil { 188 return nil, err 189 } 190 } 191 resp, err := rc.conn.Do("scan", keyStart, keyEnd, limit) 192 if err != nil { 193 return nil, err 194 } 195 return resp, nil 196 } 197 198 // StartAndGC start memcache adapter. 199 // config string is like {"conn":"connection info"}. 200 // if connecting error, return. 201 func (rc *Cache) StartAndGC(config string) error { 202 var cf map[string]string 203 json.Unmarshal([]byte(config), &cf) 204 if _, ok := cf["conn"]; !ok { 205 return errors.New("config has no conn key") 206 } 207 rc.conninfo = strings.Split(cf["conn"], ";") 208 if rc.conn == nil { 209 if err := rc.connectInit(); err != nil { 210 return err 211 } 212 } 213 return nil 214 } 215 216 // connect to memcache and keep the connection. 217 func (rc *Cache) connectInit() error { 218 conninfoArray := strings.Split(rc.conninfo[0], ":") 219 host := conninfoArray[0] 220 port, e := strconv.Atoi(conninfoArray[1]) 221 if e != nil { 222 return e 223 } 224 var err error 225 rc.conn, err = ssdb.Connect(host, port) 226 return err 227 } 228 229 func init() { 230 cache.Register("ssdb", NewSsdbCache) 231 }