114 lines
2.3 KiB
Go
Executable File
114 lines
2.3 KiB
Go
Executable File
package storage
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"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
|
|
}
|