walletdb: add ForEachBucket to the ReadTx with bbolt implementation
This commit extends the ReadTx (and ReadWriteTx) interface with ForEachBucket which can be used to iterate through all top level buckets. This is a missing piece from the walletdb abstraction which will allow us to iterate all keys in a walletdb opening the possibility to build generic tools to browse and edit walletdb files regardless of the underlying driver.
This commit is contained in:
parent
50978fcf79
commit
c6f007b74a
3 changed files with 37 additions and 0 deletions
|
@ -60,6 +60,15 @@ func (tx *transaction) ReadBucket(key []byte) walletdb.ReadBucket {
|
||||||
return tx.ReadWriteBucket(key)
|
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 {
|
func (tx *transaction) ReadWriteBucket(key []byte) walletdb.ReadWriteBucket {
|
||||||
boltBucket := tx.boltTx.Bucket(key)
|
boltBucket := tx.boltTx.Bucket(key)
|
||||||
if boltBucket == nil {
|
if boltBucket == nil {
|
||||||
|
|
|
@ -19,6 +19,9 @@ type ReadTx interface {
|
||||||
// described by the key does not exist, nil is returned.
|
// described by the key does not exist, nil is returned.
|
||||||
ReadBucket(key []byte) ReadBucket
|
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
|
// Rollback closes the transaction, discarding changes (if any) if the
|
||||||
// database was modified by a write transaction.
|
// database was modified by a write transaction.
|
||||||
Rollback() error
|
Rollback() error
|
||||||
|
|
|
@ -540,6 +540,31 @@ func testNamespaceAndTxInterfaces(tc *testContext, namespaceKey string) bool {
|
||||||
return false
|
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.
|
// Test the bucket interface via a managed read-write transaction.
|
||||||
// Also, put a series of values and force a rollback so the following
|
// Also, put a series of values and force a rollback so the following
|
||||||
// code can ensure the values were not stored.
|
// code can ensure the values were not stored.
|
||||||
|
|
Loading…
Reference in a new issue