package storage import ( "errors" "fmt" "gitea.inhome.blapointe.com/local/storage/resolve" "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) Namespaces() ([][]string, error) { resp, err := m.client.Do("KEYS", "*") if err != nil { return nil, err } keys := map[string][]string{} results, ok := resp.([]interface{}) if !ok { return nil, ErrNotFound } for _, key := range results { pieces := resolve.UnNamespace(fmt.Sprintf("%s", key)) if len(pieces) < 2 { continue } pieces = pieces[:len(pieces)-1] keys[fmt.Sprint(pieces)] = pieces } result := make([][]string, 0, len(keys)) for _, v := range keys { result = append(result, v) } return result, nil } func (m *Redis) List(ns []string, limits ...string) ([]string, error) { limits = resolve.Limits(limits) limits[0] = resolve.Namespace(append(ns, limits[0])) limits[1] = resolve.Namespace(append(ns, limits[1])) resp, err := m.client.Do("KEYS", "*") if err != nil { return nil, err } keys := []string{} results, ok := resp.([]interface{}) if !ok { return nil, ErrNotFound } 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 = resolve.Namespace(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 := resolve.Namespace(append(ns, key)) _, err := m.client.Do("SET", namespace, value) return err }