Skip to content

Commit d874c5d

Browse files
committed
[db] add BoltDB.BucketExists() method
1 parent 50e7025 commit d874c5d

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

db/db_bolt.go

+32-19
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@ import (
2020

2121
const fileMode = 0600
2222

23-
// boltDB is KVStore implementation based bolt DB
24-
type boltDB struct {
23+
// BoltDB is KVStore implementation based bolt DB
24+
type BoltDB struct {
2525
db *bolt.DB
2626
path string
2727
config config.DB
2828
}
2929

3030
// NewBoltDB instantiates an BoltDB with implements KVStore
31-
func NewBoltDB(cfg config.DB) KVStore {
32-
return &boltDB{
31+
func NewBoltDB(cfg config.DB) *BoltDB {
32+
return &BoltDB{
3333
db: nil,
3434
path: cfg.DbPath,
3535
config: cfg,
3636
}
3737
}
3838

3939
// Start opens the BoltDB (creates new file if not existing yet)
40-
func (b *boltDB) Start(_ context.Context) error {
40+
func (b *BoltDB) Start(_ context.Context) error {
4141
db, err := bolt.Open(b.path, fileMode, nil)
4242
if err != nil {
4343
return errors.Wrap(ErrIO, err.Error())
@@ -47,7 +47,7 @@ func (b *boltDB) Start(_ context.Context) error {
4747
}
4848

4949
// Stop closes the BoltDB
50-
func (b *boltDB) Stop(_ context.Context) error {
50+
func (b *BoltDB) Stop(_ context.Context) error {
5151
if b.db != nil {
5252
if err := b.db.Close(); err != nil {
5353
return errors.Wrap(ErrIO, err.Error())
@@ -57,7 +57,7 @@ func (b *boltDB) Stop(_ context.Context) error {
5757
}
5858

5959
// Put inserts a <key, value> record
60-
func (b *boltDB) Put(namespace string, key, value []byte) (err error) {
60+
func (b *BoltDB) Put(namespace string, key, value []byte) (err error) {
6161
for c := uint8(0); c < b.config.NumRetries; c++ {
6262
if err = b.db.Update(func(tx *bolt.Tx) error {
6363
bucket, err := tx.CreateBucketIfNotExists([]byte(namespace))
@@ -76,7 +76,7 @@ func (b *boltDB) Put(namespace string, key, value []byte) (err error) {
7676
}
7777

7878
// Get retrieves a record
79-
func (b *boltDB) Get(namespace string, key []byte) ([]byte, error) {
79+
func (b *BoltDB) Get(namespace string, key []byte) ([]byte, error) {
8080
var value []byte
8181
err := b.db.View(func(tx *bolt.Tx) error {
8282
bucket := tx.Bucket([]byte(namespace))
@@ -102,7 +102,7 @@ func (b *boltDB) Get(namespace string, key []byte) ([]byte, error) {
102102
}
103103

104104
// Filter returns <k, v> pair in a bucket that meet the condition
105-
func (b *boltDB) Filter(namespace string, cond Condition, minKey, maxKey []byte) ([][]byte, [][]byte, error) {
105+
func (b *BoltDB) Filter(namespace string, cond Condition, minKey, maxKey []byte) ([][]byte, [][]byte, error) {
106106
var fk, fv [][]byte
107107
if err := b.db.View(func(tx *bolt.Tx) error {
108108
bucket := tx.Bucket([]byte(namespace))
@@ -148,7 +148,7 @@ func (b *boltDB) Filter(namespace string, cond Condition, minKey, maxKey []byte)
148148
}
149149

150150
// Range retrieves values for a range of keys
151-
func (b *boltDB) Range(namespace string, key []byte, count uint64) ([][]byte, error) {
151+
func (b *BoltDB) Range(namespace string, key []byte, count uint64) ([][]byte, error) {
152152
value := make([][]byte, count)
153153
err := b.db.View(func(tx *bolt.Tx) error {
154154
bucket := tx.Bucket([]byte(namespace))
@@ -182,7 +182,7 @@ func (b *boltDB) Range(namespace string, key []byte, count uint64) ([][]byte, er
182182
}
183183

184184
// GetBucketByPrefix retrieves all bucket those with const namespace prefix
185-
func (b *boltDB) GetBucketByPrefix(namespace []byte) ([][]byte, error) {
185+
func (b *BoltDB) GetBucketByPrefix(namespace []byte) ([][]byte, error) {
186186
allKey := make([][]byte, 0)
187187
err := b.db.View(func(tx *bolt.Tx) error {
188188
if err := tx.ForEach(func(name []byte, b *bolt.Bucket) error {
@@ -201,7 +201,7 @@ func (b *boltDB) GetBucketByPrefix(namespace []byte) ([][]byte, error) {
201201
}
202202

203203
// GetKeyByPrefix retrieves all keys those with const prefix
204-
func (b *boltDB) GetKeyByPrefix(namespace, prefix []byte) ([][]byte, error) {
204+
func (b *BoltDB) GetKeyByPrefix(namespace, prefix []byte) ([][]byte, error) {
205205
allKey := make([][]byte, 0)
206206
err := b.db.View(func(tx *bolt.Tx) error {
207207
buck := tx.Bucket(namespace)
@@ -220,7 +220,7 @@ func (b *boltDB) GetKeyByPrefix(namespace, prefix []byte) ([][]byte, error) {
220220
}
221221

222222
// Delete deletes a record,if key is nil,this will delete the whole bucket
223-
func (b *boltDB) Delete(namespace string, key []byte) (err error) {
223+
func (b *BoltDB) Delete(namespace string, key []byte) (err error) {
224224
numRetries := b.config.NumRetries
225225
for c := uint8(0); c < numRetries; c++ {
226226
if key == nil {
@@ -250,7 +250,7 @@ func (b *boltDB) Delete(namespace string, key []byte) (err error) {
250250
}
251251

252252
// WriteBatch commits a batch
253-
func (b *boltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
253+
func (b *BoltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
254254
succeed := true
255255
kvsb.Lock()
256256
defer func() {
@@ -306,12 +306,25 @@ func (b *boltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
306306
return err
307307
}
308308

309+
// BucketExists returns true if bucket exists
310+
func (b *BoltDB) BucketExists(namespace string) bool {
311+
var exist bool
312+
_ = b.db.View(func(tx *bolt.Tx) error {
313+
bucket := tx.Bucket([]byte(namespace))
314+
if bucket != nil {
315+
exist = true
316+
}
317+
return nil
318+
})
319+
return exist
320+
}
321+
309322
// ======================================
310323
// below functions used by RangeIndex
311324
// ======================================
312325

313326
// Insert inserts a value into the index
314-
func (b *boltDB) Insert(name []byte, key uint64, value []byte) error {
327+
func (b *BoltDB) Insert(name []byte, key uint64, value []byte) error {
315328
var err error
316329
for i := uint8(0); i < b.config.NumRetries; i++ {
317330
if err = b.db.Update(func(tx *bolt.Tx) error {
@@ -346,7 +359,7 @@ func (b *boltDB) Insert(name []byte, key uint64, value []byte) error {
346359
}
347360

348361
// Seek returns value by the key
349-
func (b *boltDB) Seek(name []byte, key uint64) ([]byte, error) {
362+
func (b *BoltDB) Seek(name []byte, key uint64) ([]byte, error) {
350363
var value []byte
351364
err := b.db.View(func(tx *bolt.Tx) error {
352365
bucket := tx.Bucket(name)
@@ -367,7 +380,7 @@ func (b *boltDB) Seek(name []byte, key uint64) ([]byte, error) {
367380
}
368381

369382
// Remove removes an existing key
370-
func (b *boltDB) Remove(name []byte, key uint64) error {
383+
func (b *BoltDB) Remove(name []byte, key uint64) error {
371384
var err error
372385
for i := uint8(0); i < b.config.NumRetries; i++ {
373386
if err = b.db.Update(func(tx *bolt.Tx) error {
@@ -399,7 +412,7 @@ func (b *boltDB) Remove(name []byte, key uint64) error {
399412
}
400413

401414
// Purge deletes an existing key and all keys before it
402-
func (b *boltDB) Purge(name []byte, key uint64) error {
415+
func (b *BoltDB) Purge(name []byte, key uint64) error {
403416
var err error
404417
for i := uint8(0); i < b.config.NumRetries; i++ {
405418
if err = b.db.Update(func(tx *bolt.Tx) error {
@@ -432,7 +445,7 @@ func (b *boltDB) Purge(name []byte, key uint64) error {
432445
// ======================================
433446

434447
// intentionally fail to test DB can successfully rollback
435-
func (b *boltDB) batchPutForceFail(namespace string, key [][]byte, value [][]byte) error {
448+
func (b *BoltDB) batchPutForceFail(namespace string, key [][]byte, value [][]byte) error {
436449
return b.db.Update(func(tx *bolt.Tx) error {
437450
bucket, err := tx.CreateBucketIfNotExists([]byte(namespace))
438451
if err != nil {

db/db_bolt_test.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,30 @@ import (
1717
"github.com/iotexproject/iotex-core/testutil"
1818
)
1919

20+
func TestBucketExists(t *testing.T) {
21+
r := require.New(t)
22+
testPath, err := testutil.PathOfTempFile("test-bucket")
23+
r.NoError(err)
24+
defer func() {
25+
testutil.CleanupPath(t, testPath)
26+
}()
27+
28+
cfg := config.Default.DB
29+
cfg.DbPath = testPath
30+
kv := NewBoltDB(cfg)
31+
ctx := context.Background()
32+
r.NoError(kv.Start(ctx))
33+
defer kv.Stop(ctx)
34+
r.False(kv.BucketExists("name"))
35+
r.NoError(kv.Put("name", []byte("key"), []byte{}))
36+
r.True(kv.BucketExists("name"))
37+
}
38+
2039
func BenchmarkBoltDB_Get(b *testing.B) {
2140
runBenchmark := func(b *testing.B, size int) {
2241
path, err := testutil.PathOfTempFile("boltdb")
2342
require.NoError(b, err)
24-
db := boltDB{
43+
db := BoltDB{
2544
path: path,
2645
config: config.Default.DB,
2746
}

db/db_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func TestBatchRollback(t *testing.T) {
9999
assert.Equal(testV1[2], value)
100100

101101
testV := [3][]byte{[]byte("value1.1"), []byte("value2.1"), []byte("value3.1")}
102-
kvboltDB := kvStore.(*boltDB)
102+
kvboltDB := kvStore.(*BoltDB)
103103
err = kvboltDB.batchPutForceFail(bucket1, testK1[:], testV[:])
104104
assert.NotNil(err)
105105

0 commit comments

Comments
 (0)