diff --git a/walletdb/bdb/db.go b/walletdb/bdb/db.go index e6a782f..288ffe1 100644 --- a/walletdb/bdb/db.go +++ b/walletdb/bdb/db.go @@ -60,6 +60,15 @@ func (tx *transaction) ReadBucket(key []byte) walletdb.ReadBucket { return tx.ReadWriteBucket(key) } +// ForEachBucket will iterate through all top level buckets. +func (tx *transaction) ForEachBucket(fn func(key []byte) error) error { + return convertErr(tx.boltTx.ForEach( + func(name []byte, _ *bbolt.Bucket) error { + return fn(name) + }, + )) +} + func (tx *transaction) ReadWriteBucket(key []byte) walletdb.ReadWriteBucket { boltBucket := tx.boltTx.Bucket(key) if boltBucket == nil { diff --git a/walletdb/interface.go b/walletdb/interface.go index 40fb19e..b6abe66 100644 --- a/walletdb/interface.go +++ b/walletdb/interface.go @@ -19,6 +19,9 @@ type ReadTx interface { // described by the key does not exist, nil is returned. ReadBucket(key []byte) ReadBucket + // ForEachBucket will iterate through all top level buckets. + ForEachBucket(func(key []byte) error) error + // Rollback closes the transaction, discarding changes (if any) if the // database was modified by a write transaction. Rollback() error diff --git a/walletdb/walletdbtest/interface.go b/walletdb/walletdbtest/interface.go index 037de1c..da17f12 100644 --- a/walletdb/walletdbtest/interface.go +++ b/walletdb/walletdbtest/interface.go @@ -540,6 +540,31 @@ func testNamespaceAndTxInterfaces(tc *testContext, namespaceKey string) bool { return false } + // Test that we can read the top level buckets. + var topLevelBuckets []string + walletdb.View(tc.db, func(tx walletdb.ReadTx) error { + return tx.ForEachBucket(func(key []byte) error { + topLevelBuckets = append(topLevelBuckets, string(key)) + return nil + }) + }) + if err != nil { + if err != errSubTestFail { + tc.t.Errorf("%v", err) + } + return false + } + + if len(topLevelBuckets) != 1 { + tc.t.Errorf("ForEachBucket: expected only one top level bucket") + return false + } + if topLevelBuckets[0] != namespaceKey { + tc.t.Errorf("ForEachBucket: expected %v, got %v", namespaceKey, + topLevelBuckets[0]) + return false + } + // Test the bucket interface via a managed read-write transaction. // Also, put a series of values and force a rollback so the following // code can ensure the values were not stored.