working on List

master
bel 2019-06-21 17:13:18 -06:00
parent 6ac77d247e
commit ade973d19d
13 changed files with 178 additions and 2 deletions

19
bolt.go
View File

@ -13,6 +13,25 @@ func NewBolt(path string) (*Bolt, error) {
}, err
}
func (b *Bolt) List(ns []string, limits ...string) ([]string, error) {
namespace := resolveNamespace(ns)
limits = resolveLimits(limits)
found := []string{}
err := b.db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(namespace))
if bucket == nil {
return nil
}
c := bucket.Cursor()
for k, _ := c.Seek([]byte(limits[0])); k != nil; k, _ = c.Next() {
found = append(found, string(k))
}
return nil
})
return found, err
}
func (b *Bolt) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
var result []byte

View File

@ -1,6 +1,7 @@
package storage
import (
"errors"
"os"
"path"
"time"
@ -25,6 +26,10 @@ func NewCache(path ...string) (*Cache, error) {
return c, err
}
func (c *Cache) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (c *Cache) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
v, ok := c.db.Get(path.Join(namespace, key))

74
cli/main.go Normal file
View File

@ -0,0 +1,74 @@
package main
import (
"bufio"
"fmt"
"local/args"
"local/storage"
"log"
"os"
"strings"
"time"
)
func main() {
as := args.NewArgSet()
as.Append(args.STRING, "addr", "addr of store", "")
as.Append(args.STRING, "db", "type of store", "map")
as.Append(args.STRING, "user", "user of store", "")
as.Append(args.STRING, "pass", "pass of store", "")
as.Append(args.STRING, "do", "[get set]", "get")
as.Append(args.STRING, "k", "key", "key")
as.Append(args.STRING, "v", "value", "value")
if err := as.Parse(); err != nil {
panic(err)
}
db, err := storage.New(
storage.TypeFromString(as.Get("db").GetString()),
as.Get("addr").GetString(),
as.Get("user").GetString(),
as.Get("pass").GetString(),
)
if err != nil {
panic(err)
}
start := time.Now()
var b []byte
switch strings.ToLower(as.Get("do").GetString()) {
case "get":
b, err = db.Get(as.Get("k").GetString())
case "set":
err = db.Set(as.Get("k").GetString(), []byte(as.Get("v").GetString()))
case "cli":
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
line, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
s := strings.Split(line, " ")
s[len(s)-1] = strings.TrimSpace(s[len(s)-1])
for len(s) < 3 {
s = append(s, "")
}
start := time.Now()
switch strings.ToLower(s[0]) {
case "get":
b, err := db.Get(s[1])
stop := time.Now()
log.Printf("(%v) %v: %s => %s", stop.Sub(start), err, s[1], b)
case "set":
err := db.Set(s[1], []byte(s[2]))
stop := time.Now()
log.Printf("(%v) %v: %s", stop.Sub(start), err, s[1])
}
}
default:
log.Fatal("-do not in [get set]")
}
stop := time.Now()
log.Printf("(%v) %v: %s", stop.Sub(start), err, b)
}

16
db.go
View File

@ -8,6 +8,7 @@ import (
type DB interface {
Get(string, ...string) ([]byte, error)
Set(string, []byte, ...string) error
List([]string, ...string) ([]string, error)
Close() error
}
@ -57,3 +58,18 @@ func resolveNamespace(ns []string) string {
}
return namespace
}
func resolveLimits(input []string) []string {
output := []string{"", ""}
if len(input) > 0 {
output[0] = input[0]
} else {
output[0] = " "
}
if len(input) > 1 {
output[1] = input[1]
} else {
output[1] = "}}}}}}}}}}}}}"
}
return output[:]
}

View File

@ -15,6 +15,14 @@ type mock struct {
m map[string][]byte
}
func (mock *mock) List(ns []string, limits ...string) ([]string, error) {
keys := []string{}
for k := range mock.m {
keys = append(keys, k)
}
return keys, nil
}
func (mock *mock) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
v, ok := mock.m[path.Join(namespace, key)]
@ -143,6 +151,14 @@ func TestImplementations(t *testing.T) {
t.Errorf("cannot get %T: %v", db, err)
} else if !bytes.Equal(v, validValue) {
t.Errorf("wrong get %T: %q vs %q", db, v, validValue)
} else if keys, err := db.List(nil); err != nil || len(keys) < 1 {
t.Errorf("cannot List(): %v", err)
} else if keys[0] != validKey {
t.Errorf("List()[0] != %s: %s", validKey, keys[0])
} else if keys, err := db.List(nil, validKey[:1]); err != nil || len(keys) < 1 {
t.Errorf("cannot List(prefix): %v", err)
} else if keys[0] != validKey {
t.Errorf("List(prefix)[0] != %s: %s", validKey, keys[0])
} else {
t.Logf("%25T GET: %s", db, v)
}

View File

@ -6,6 +6,7 @@ import (
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/filter"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/util"
)
type LevelDB struct {
@ -21,6 +22,18 @@ func NewLevelDB(path string) (*LevelDB, error) {
}, err
}
func (ldb *LevelDB) List(ns []string, limits ...string) ([]string, error) {
keys := []string{}
r := util.BytesPrefix([]byte{})
it := ldb.db.NewIterator(r, nil)
defer it.Release()
for it.Next() {
keys = append(keys, string(it.Key()))
}
err := it.Error()
return keys, err
}
func (ldb *LevelDB) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
snapshot, err := ldb.db.GetSnapshot()

5
map.go
View File

@ -1,6 +1,7 @@
package storage
import (
"errors"
"fmt"
)
@ -28,6 +29,10 @@ func (m *Map) Close() error {
return nil
}
func (m *Map) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (m *Map) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
if _, ok := (*m)[namespace]; !ok {

View File

@ -1,6 +1,7 @@
package storage
import (
"errors"
"net"
"path"
@ -47,6 +48,10 @@ func NewMemcache(addr string, addrs ...string) (*Memcache, error) {
return &Memcache{db: db}, nil
}
func (mc *Memcache) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (mc *Memcache) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
v, err := mc.db.Get(path.Join(namespace, key))

View File

@ -1,6 +1,7 @@
package storage
import (
"errors"
"net"
"path"
@ -69,6 +70,10 @@ func NewMemcacheCluster(addr string, addrs ...string) (*MemcacheCluster, error)
return &MemcacheCluster{db: db}, nil
}
func (mc *MemcacheCluster) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (mc *MemcacheCluster) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
v, err := mc.db.Get(path.Join(namespace, key))

View File

@ -2,6 +2,7 @@ package storage
import (
"bytes"
"errors"
"io/ioutil"
"strings"
@ -17,6 +18,10 @@ func NewMinio(addr, user, pass string) (*Minio, error) {
return &Minio{db: db}, err
}
func (m *Minio) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (m *Minio) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
obj, err := m.db.GetObject(namespace, key, minio.GetObjectOptions{})

View File

@ -2,6 +2,7 @@ package storage
import (
"context"
"errors"
"strings"
"time"
@ -53,6 +54,10 @@ func NewMongo(addr string, auth ...string) (*Mongo, error) {
return &Mongo{db: db}, nil
}
func (mg *Mongo) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (mg *Mongo) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)

View File

@ -3,7 +3,6 @@ package storage
import (
"errors"
"fmt"
"log"
"time"
"github.com/gomodule/redigo/redis"
@ -33,9 +32,12 @@ func (m *Redis) Close() error {
return m.client.Close()
}
func (m *Redis) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
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

View File

@ -1,6 +1,8 @@
package storage
import (
"errors"
riak "github.com/basho/riak-go-client"
)
@ -28,6 +30,10 @@ func NewRiak(addr string, addrs ...string) (*Riak, error) {
}, err
}
func (r *Riak) List(ns []string, limits ...string) ([]string, error) {
return nil, errors.New("not impl")
}
func (r *Riak) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
obj := &riak.Object{}