single db with prefixes, dump/restore, blacklisting on user deletion

This commit is contained in:
ston1th 2018-09-23 23:56:12 +02:00
commit d4971cda89
20 changed files with 264 additions and 163 deletions

View file

@ -2,7 +2,11 @@
package store
import "github.com/boltdb/bolt"
import (
"encoding/json"
"github.com/boltdb/bolt"
"io"
)
const defaultBoltBucket = "default"
@ -15,15 +19,13 @@ func NewBoltStore(file string, m Marshaler) (bs *BoltStore, err error) {
if m == nil {
m = NewGOB()
}
db, err := bolt.Open(file, 0666, nil)
db, err := bolt.Open(file, 0640, nil)
if err != nil {
return
}
if err = db.Update(func(tx *bolt.Tx) error {
if _, err := tx.CreateBucketIfNotExists([]byte(defaultBoltBucket)); err != nil {
return err
}
return nil
if err = db.Update(func(tx *bolt.Tx) (err error) {
_, err = tx.CreateBucketIfNotExists([]byte(defaultBoltBucket))
return
}); err != nil {
return
}
@ -31,6 +33,53 @@ func NewBoltStore(file string, m Marshaler) (bs *BoltStore, err error) {
return
}
type dump struct {
k string `json:"k"`
v []byte `json:"v"`
}
func (bs *BoltStore) Dump(w io.Writer) (err error) {
if w == nil {
return ErrWriterIsNil
}
var d []dump
err = bs.ForEach(func(k string, v []byte) error {
d = append(d, dump{k, v})
return nil
})
if err != nil {
return
}
return json.NewEncoder(w).Encode(d)
}
func (bs *BoltStore) Restore(r io.Reader) (err error) {
if r == nil {
return ErrReaderIsNil
}
var d []dump
err = json.NewDecoder(r).Decode(&d)
if err != nil {
return
}
if err = bs.db.Update(func(tx *bolt.Tx) (err error) {
if err = tx.DeleteBucket([]byte(defaultBoltBucket)); err != nil {
return
}
_, err = tx.CreateBucket([]byte(defaultBoltBucket))
return
}); err != nil {
return
}
return bs.db.Update(func(tx *bolt.Tx) (err error) {
b := tx.Bucket([]byte(defaultBoltBucket))
for _, v := range d {
b.Put([]byte(v.k), v.v)
}
return nil
})
}
func (bs *BoltStore) Get(key string, v interface{}) (err error) {
err = bs.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(defaultBoltBucket)).Get([]byte(key))
@ -46,10 +95,13 @@ func (bs *BoltStore) Get(key string, v interface{}) (err error) {
}
func (bs *BoltStore) Set(key string, v interface{}) error {
return bs.db.Update(func(tx *bolt.Tx) error {
b, err := bs.Marshal(v)
if err != nil {
return err
return bs.db.Update(func(tx *bolt.Tx) (err error) {
var b []byte
if v != nil {
b, err = bs.Marshal(v)
if err != nil {
return
}
}
return tx.Bucket([]byte(defaultBoltBucket)).Put([]byte(key), b)
})