storage/redis.go

114 lines
2.3 KiB
Go
Executable File

package storage
import (
"errors"
"fmt"
"gogs.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
}