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