package storage import ( "errors" "fmt" "time" "github.com/gomodule/redigo/redis" ) type Redis struct { client redis.Conn } func NewRedis(addr, user, pass string) (*Redis, error) { opts := []redis.DialOption{} if pass != "" { opts = append(opts, redis.DialPassword(pass)) } opts = append(opts, redis.DialConnectTimeout(time.Second*3)) client, err := redis.Dial("tcp", addr, opts...) return &Redis{ client: client, }, err } func (m *Redis) String() string { return fmt.Sprintf("%v", *m) } func (m *Redis) Close() error { return m.client.Close() } func (m *Redis) List(ns []string, limits ...string) ([]string, error) { limits = resolveLimits(limits) limits[0] = resolveNamespace(append(ns, limits[0])) limits[1] = resolveNamespace(append(ns, limits[1])) resp, err := m.client.Do("KEYS", "*") if err != nil { return nil, err } keys := []string{} if results, ok := resp.([]interface{}); !ok { return nil, ErrNotFound } else { for i := range results { _, ok := results[i].([]uint8) if !ok { return nil, errors.New("not a []byte key") } k := fmt.Sprintf("%s", results[i]) if k < limits[0] { continue } if k > limits[1] { break } keys = append(keys, k) } } return keys, nil } func (m *Redis) Get(key string, ns ...string) ([]byte, error) { key = resolveNamespace(append(ns, key)) resp, err := m.client.Do("GET", key) if err != nil { return nil, err } if resp == nil { return nil, ErrNotFound } b, ok := resp.([]byte) if !ok { return nil, errors.New("resp not a []byte") } return b, nil } func (m *Redis) Set(key string, value []byte, ns ...string) error { namespace := resolveNamespace(append(ns, key)) _, err := m.client.Do("SET", namespace, value) return err }