diff --git a/db.go b/db.go index 68fd83c..303f504 100644 --- a/db.go +++ b/db.go @@ -2,6 +2,7 @@ package storage import ( "fmt" + "strings" ) type DB interface { @@ -20,6 +21,8 @@ func New(key Type, params ...string) (db DB, err error) { }() err = ErrNotImpl switch key { + case REDIS: + db, err = NewRedis(params[0], params[1], params[2]) case MAP: db = NewMap() err = nil @@ -44,7 +47,13 @@ func New(key Type, params ...string) (db DB, err error) { func resolveNamespace(ns []string) string { namespace := DefaultNamespace if len(ns) > 0 { - namespace = ns[0] + segments := []string{} + for i := range ns { + if ns[i] != "" { + segments = append(segments, ns[i]) + } + } + namespace = strings.Join(segments, ".") } return namespace } diff --git a/db_test.go b/db_test.go index 8819fc1..d068f17 100644 --- a/db_test.go +++ b/db_test.go @@ -58,6 +58,12 @@ func TestImplementations(t *testing.T) { cases = append(cases, cacheFile) } + if redis, err := NewRedis("localhost:6379", "", ""); err != nil { + t.Errorf("cannot make redis: %v", err) + } else { + cases = append(cases, redis) + } + if bolt, err := NewBolt(path.Join(dir, "bolt")); err != nil { t.Errorf("cannot make bolt: %v", err) } else { @@ -155,6 +161,10 @@ func TestToFromString(t *testing.T) { key: "map", t: MAP, }, + { + key: "redis", + t: REDIS, + }, { key: "minio", t: MINIO, diff --git a/mongo.go b/mongo.go index ca698e9..332c857 100644 --- a/mongo.go +++ b/mongo.go @@ -5,12 +5,12 @@ import ( "strings" "time" - "github.com/mongodb/mongo-go-driver/mongo" - "github.com/mongodb/mongo-go-driver/mongo/options" - "github.com/mongodb/mongo-go-driver/mongo/readconcern" - "github.com/mongodb/mongo-go-driver/mongo/readpref" - "github.com/mongodb/mongo-go-driver/mongo/writeconcern" - "gopkg.in/mgo.v2/bson" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/mongo/readconcern" + "go.mongodb.org/mongo-driver/mongo/readpref" + "go.mongodb.org/mongo-driver/mongo/writeconcern" ) type Mongo struct { @@ -26,8 +26,8 @@ func NewMongo(addr string, auth ...string) (*Mongo, error) { Password: auth[1], }) } - db, err := mongo.NewClientWithOptions( - "mongodb://"+addr, + db, err := mongo.NewClient( + options.Client().ApplyURI("mongodb://"+addr), options.Client().SetReadConcern(readconcern.Local()), options.Client().SetReadPreference(readpref.PrimaryPreferred()), options.Client().SetWriteConcern(writeconcern.New( @@ -68,8 +68,8 @@ func (mg *Mongo) Get(key string, ns ...string) ([]byte, error) { return nil, ErrNotFound } - elem, err := cursor.DecodeBytes() - if err != nil { + var elem bson.Raw + if err := cursor.Decode(&elem); err != nil { return nil, err } raw, err := elem.LookupErr("value") diff --git a/redis.go b/redis.go new file mode 100644 index 0000000..205c9a7 --- /dev/null +++ b/redis.go @@ -0,0 +1,57 @@ +package storage + +import ( + "errors" + "fmt" + "log" + "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*10)) + 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) Get(key string, ns ...string) ([]byte, error) { + key = resolveNamespace(append(ns, key)) + log.Println(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 +} diff --git a/type.go b/type.go index b90c987..23944dc 100644 --- a/type.go +++ b/type.go @@ -8,7 +8,9 @@ type Type int const ( MAP = Type(iota) + REDIS = Type(iota) BOLT = Type(iota) + COCKROACH = Type(iota) CACHE = Type(iota) LEVELDB = Type(iota) MEMCACHE = Type(iota) @@ -19,8 +21,12 @@ const ( func (t Type) String() string { switch t { + case REDIS: + return "redis" case MAP: return "map" + case COCKROACH: + return "cockroach" case BOLT: return "bolt" case MINIO: