2024-03-09 11:46:48 +00:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ KVStore = (*BboltDBKVStore)(nil)
|
|
|
|
|
|
|
|
type BboltDBKVStore struct {
|
|
|
|
db *bbolt.DB
|
|
|
|
bucket *bbolt.Bucket
|
|
|
|
bucketName string
|
|
|
|
root bool
|
|
|
|
dbPath string
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Open() error {
|
2024-03-09 11:46:48 +00:00
|
|
|
if b.root && b.db == nil {
|
|
|
|
db, err := bbolt.Open(b.dbPath, 0666, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
b.db = db
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:15:54 +00:00
|
|
|
if len(b.bucketName) > 0 {
|
2024-03-09 11:46:48 +00:00
|
|
|
err := b.db.Update(func(txn *bbolt.Tx) error {
|
2024-03-09 12:15:54 +00:00
|
|
|
var bucket *bbolt.Bucket
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if b.bucket == nil {
|
|
|
|
bucket, err = txn.CreateBucketIfNotExists([]byte(b.bucketName))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bucket, err = b.bucket.CreateBucketIfNotExists([]byte(b.bucketName))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-03-09 11:46:48 +00:00
|
|
|
}
|
2024-03-09 12:15:54 +00:00
|
|
|
|
2024-03-09 11:46:48 +00:00
|
|
|
b.bucket = bucket
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Close() error {
|
2024-03-09 11:46:48 +00:00
|
|
|
if b.root && b.db != nil {
|
|
|
|
err := b.db.Close()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Get(key []byte) ([]byte, error) {
|
2024-03-09 11:46:48 +00:00
|
|
|
if b.root {
|
|
|
|
return nil, errors.New("Cannot get from root")
|
|
|
|
}
|
|
|
|
|
|
|
|
var val []byte
|
|
|
|
err := b.db.View(func(txn *bbolt.Tx) error {
|
|
|
|
bucket := txn.Bucket([]byte(b.bucketName))
|
|
|
|
val = bucket.Get(key)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return val, nil
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Put(key []byte, value []byte) error {
|
2024-03-09 11:46:48 +00:00
|
|
|
|
|
|
|
if b.root {
|
|
|
|
return errors.New("Cannot put from root")
|
|
|
|
}
|
|
|
|
|
|
|
|
err := b.db.Update(func(txn *bbolt.Tx) error {
|
|
|
|
bucket := txn.Bucket([]byte(b.bucketName))
|
|
|
|
err := bucket.Put(key, value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Delete(key []byte) error {
|
2024-03-09 11:46:48 +00:00
|
|
|
if b.root {
|
|
|
|
return errors.New("Cannot delete from root")
|
|
|
|
}
|
|
|
|
|
|
|
|
err := b.db.Update(func(txn *bbolt.Tx) error {
|
|
|
|
bucket := txn.Bucket([]byte(b.bucketName))
|
|
|
|
err := bucket.Delete(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-03-09 12:11:53 +00:00
|
|
|
func (b *BboltDBKVStore) Bucket(prefix string) (KVStore, error) {
|
2024-03-09 11:46:48 +00:00
|
|
|
return &BboltDBKVStore{
|
|
|
|
db: b.db,
|
2024-03-09 12:15:54 +00:00
|
|
|
bucket: b.bucket,
|
2024-03-09 11:46:48 +00:00
|
|
|
bucketName: prefix,
|
|
|
|
root: false,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBboltDBKVStore(dbPath string) *BboltDBKVStore {
|
|
|
|
return &BboltDBKVStore{
|
|
|
|
dbPath: dbPath,
|
|
|
|
root: true,
|
|
|
|
}
|
|
|
|
}
|