diff --git a/db.go b/db.go index c6bd033..68fd83c 100644 --- a/db.go +++ b/db.go @@ -25,6 +25,8 @@ func New(key Type, params ...string) (db DB, err error) { err = nil case BOLT: db, err = NewBolt(params[0]) + case MINIO: + db, err = NewMinio(params[0], params[1], params[2]) case CACHE: db, err = NewCache(params...) case LEVELDB: diff --git a/minio.go b/minio.go new file mode 100644 index 0000000..c1e0a02 --- /dev/null +++ b/minio.go @@ -0,0 +1,57 @@ +package storage + +import ( + "bytes" + "io/ioutil" + "strings" + + minio "github.com/minio/minio-go" +) + +type Minio struct { + db *minio.Client +} + +func NewMinio(addr, user, pass string) (*Minio, error) { + db, err := minio.New(addr, user, pass, strings.HasPrefix(addr, "https://")) + return &Minio{db: db}, err +} + +func (m *Minio) Get(key string, ns ...string) ([]byte, error) { + namespace := resolveNamespace(ns) + obj, err := m.db.GetObject(namespace, key, minio.GetObjectOptions{}) + if err == nil { + var stat minio.ObjectInfo + if stat, err = obj.Stat(); err == nil { + err = stat.Err + } + } + if isNotExistErr(err) { + return nil, ErrNotFound + } else if err != nil { + return nil, err + } + return ioutil.ReadAll(obj) +} + +func (m *Minio) Set(key string, value []byte, ns ...string) error { + namespace := resolveNamespace(ns) + if ok, err := m.db.BucketExists(namespace); err != nil { + return err + } else if !ok { + if err := m.db.MakeBucket(namespace, ""); err != nil { + return err + } + } + _, err := m.db.PutObject(namespace, key, bytes.NewBuffer(value), int64(len(value)), minio.PutObjectOptions{}) + return err +} + +func (m *Minio) Close() error { + m.db = nil + return nil +} + +func isNotExistErr(err error) bool { + return err != nil && strings.Contains(err.Error(), "does not exist") +} diff --git a/type.go b/type.go index fd3e971..b90c987 100644 --- a/type.go +++ b/type.go @@ -14,6 +14,7 @@ const ( MEMCACHE = Type(iota) MEMCACHECLUSTER = Type(iota) MONGO = Type(iota) + MINIO = Type(iota) ) func (t Type) String() string { @@ -22,6 +23,8 @@ func (t Type) String() string { return "map" case BOLT: return "bolt" + case MINIO: + return "minio" case CACHE: return "cache" case LEVELDB: