Store package for boltdb get/set/list
parent
f7ffe6c829
commit
9f057891bc
|
|
@ -0,0 +1,58 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BoltClient struct {
|
||||||
|
db *bolt.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBolt(path string) (*BoltClient, error) {
|
||||||
|
db, err := bolt.Open(path, 0600, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &BoltClient{
|
||||||
|
db: db,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BoltClient) Set(namespace, key string, value []byte) error {
|
||||||
|
return bc.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
bucket, err := tx.CreateBucketIfNotExists([]byte(namespace))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return bucket.Put([]byte(key), value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BoltClient) List(namespace, key string) ([]string, error) {
|
||||||
|
found := []string{}
|
||||||
|
err := bc.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(key)); k != nil; k, _ = c.Next() {
|
||||||
|
found = append(found, string(k))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return found, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BoltClient) Get(namespace, key string) ([]byte, error) {
|
||||||
|
var result []byte
|
||||||
|
err := bc.db.View(func(tx *bolt.Tx) error {
|
||||||
|
bucket := tx.Bucket([]byte(namespace))
|
||||||
|
if bucket == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
result = bucket.Get([]byte(key))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_BoltSetListGet(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
ns string
|
||||||
|
keys []string
|
||||||
|
values []string
|
||||||
|
search string
|
||||||
|
results int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ns: "namespace",
|
||||||
|
keys: []string{},
|
||||||
|
values: []string{},
|
||||||
|
search: "",
|
||||||
|
results: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: "namespace",
|
||||||
|
keys: []string{"key1", "key2", "aey3"},
|
||||||
|
values: []string{"v1", "v2", "a3"},
|
||||||
|
search: "k",
|
||||||
|
results: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: "namespace",
|
||||||
|
keys: []string{"key1", "key2", "key3"},
|
||||||
|
values: []string{"v1", "v2", "v3"},
|
||||||
|
search: "k",
|
||||||
|
results: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
tmp, err := ioutil.TempFile(".", "any*")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not make tempfile: %v", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tmp.Name())
|
||||||
|
var sc Client
|
||||||
|
sc, err = NewBolt(tmp.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create bolt %v: %v", sc, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.keys {
|
||||||
|
if err := sc.Set(c.ns, c.keys[i], []byte(c.values[i])); err != nil {
|
||||||
|
t.Errorf("failed to set bolt: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if results, err := sc.List(c.ns, c.search); err != nil {
|
||||||
|
t.Errorf("failed to list bolt: %v", err)
|
||||||
|
} else if len(results) != c.results {
|
||||||
|
t.Errorf("failed to list bolt: missing results for %q: %v, expceted %v", c.ns, len(results), len(c.keys))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.keys) > 0 {
|
||||||
|
if result, err := sc.Get(c.ns, c.keys[0]); err != nil {
|
||||||
|
t.Errorf("failed to get bolt: %v", err)
|
||||||
|
} else if string(result) != c.values[0] {
|
||||||
|
t.Errorf("failed to get bolt: got wrong result: wanted %v, got %v", c.values[0], string(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
type Client interface {
|
||||||
|
Get(string, string) ([]byte, error)
|
||||||
|
Set(string, string, []byte) error
|
||||||
|
List(string, string) ([]string, error)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue